Clang getting involved

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Clang getting involved

Anton Bikineev
Hi all.

I'm russian student from Moscow. I like C++ and
I would like to contribute to Clang not as part
of GSOC. I have already contributed to Boost.Math.

I wanted to implement a static if declaration as
an extension proposed by Herb Sutter, Andrei Alexandrescu
and Walter Bright here
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3329.pdf

This feature is used in D language.
But I don't know how it is relevant in Clang. Also I have
just found some problems. For example, I don't know
how better to represent it in AST: either as Decl or as Stmt.
If (static if) is Stmt, it is easier to implement many things
just using similar functions for if-statement.

Maybe somebody has better ideas. I will be glad to any advices.
Sorry for my English.

Best regards,
Anton.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang getting involved

Sean Silva-2



On Thu, Mar 6, 2014 at 6:36 PM, Anton Bikineev <[hidden email]> wrote:
Hi all.

I'm russian student from Moscow. I like C++ and
I would like to contribute to Clang not as part
of GSOC. I have already contributed to Boost.Math.

I wanted to implement a static if declaration as
an extension proposed by Herb Sutter, Andrei Alexandrescu
and Walter Bright here
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3329.pdf

FYI Stroustrup shot that feature down pretty hard <http://isocpp.org/blog/2013/03/n3613-static-if-considered>. It may not be the best one to implement.

-- Sean Silva
 


This feature is used in D language.
But I don't know how it is relevant in Clang. Also I have
just found some problems. For example, I don't know
how better to represent it in AST: either as Decl or as Stmt.
If (static if) is Stmt, it is easier to implement many things
just using similar functions for if-statement.

Maybe somebody has better ideas. I will be glad to any advices.
Sorry for my English.

Best regards,
Anton.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang getting involved

Anton Bikineev
> FYI Stroustrup shot that feature down pretty hard
<http://isocpp.org/blog/2013/03/n3613-static-if-considered>. It may not be
the best one to implement.

Yes, I know. But I hoped to see it like an extension. Just interesting, can
it be helpful?


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang getting involved

Jonathan Sauer
Hello,

>> FYI Stroustrup shot that feature down pretty hard
> <http://isocpp.org/blog/2013/03/n3613-static-if-considered>. It may not be
> the best one to implement.
>
> Yes, I know. But I hoped to see it like an extension. Just interesting, can
> it be helpful?

FWIW: Clang supports Microsoft's __if_exists extension when in VisualC++ mode:
<http://msdn.microsoft.com/en-us//library/x7wy9xh3.aspx> It is similar (although
more restrictive) to "static if".

I'm not sure if a clang-specific language extension would be accepted into clang,
although it could be used to evaluate the usefulness of "static if". But then
I'm biased as I'd very much like "static if" to become part of the C++ standard;
even though it's viral, as Stroustrup writes, it would reduce the need for helper
templates.


Jonathan


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang getting involved

Richard Smith
On Sat, Mar 8, 2014 at 11:31 PM, Jonathan 'Rynn' Sauer <[hidden email]> wrote:
Hello,

>> FYI Stroustrup shot that feature down pretty hard
> <http://isocpp.org/blog/2013/03/n3613-static-if-considered>. It may not be
> the best one to implement.
>
> Yes, I know. But I hoped to see it like an extension. Just interesting, can
> it be helpful?

FWIW: Clang supports Microsoft's __if_exists extension when in VisualC++ mode:
<http://msdn.microsoft.com/en-us//library/x7wy9xh3.aspx> It is similar (although
more restrictive) to "static if".

I'm not sure if a clang-specific language extension would be accepted into clang,
although it could be used to evaluate the usefulness of "static if". But then
I'm biased as I'd very much like "static if" to become part of the C++ standard;
even though it's viral, as Stroustrup writes, it would reduce the need for helper
templates.

The big problem with 'static if' is that it's three different features that have got muddled together. Those are:

1) A static if, just like #if, where the condition must be a non-dependent constant expression, and the body can be arbitrary brace-balanced token soup. This basically just allows more advanced constants in #ifs.

constexpr bool has_interval_literals() { return __has_feature(interval_literals); }
static if (has_interval_literals) {
  static_assert( [1...4) + [4...6] == [1...6], "" );
}

2) A template if, that introduces a separately-instantiable template entity (and thus introduces a scope). As is usual for templates, the body must be instantiable for some template arguments (it can't be token soup).

3) An enable if, that makes declarations visible or invisible depending on some predicate.

Of these:
- the first isn't hugely useful, since a lot of the "interesting" compile time constants for this sort of check are preprocessor constant expressions too, so #if works,
- the second is already possible using generic lambdas (but it's a little hacky):
  if_(b, [&](auto){ blah; }, [&](auto){ blah2; }) // implementation left as an exercise to the reader
- the third is already somewhat possible (using clang's attribute enable_if), and will be standardized through the concepts effort.

People sometimes want to mix these possibilities (and in particular, use the 'token soup' model in a template), but that's essentially incompatible with the tree-transformation model that is used for template instantiation by at least Clang and GCC. Given our current state, I think the only thing worth pursing is #1, and I don't think it meets Clang's criteria for language extensions.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: static if (was: Clang getting involved)

Jonathan Sauer
Hello,

> The big problem with 'static if' is that it's three different features that have got muddled together. Those are:
>
> 1) A static if, just like #if, where the condition must be a non-dependent constant expression, and the body can be arbitrary brace-balanced token soup. This basically just allows more advanced constants in #ifs.
>
> constexpr bool has_interval_literals() { return __has_feature(interval_literals); }
> static if (has_interval_literals) {
>   static_assert( [1...4) + [4...6] == [1...6], "" );
> }
>
> 2) A template if, that introduces a separately-instantiable template entity (and thus introduces a scope). As is usual for templates, the body must be instantiable for some template arguments (it can't be token soup).
>
> 3) An enable if, that makes declarations visible or invisible depending on some predicate.
>
> Of these:
> - the first isn't hugely useful, since a lot of the "interesting" compile time constants for this sort of check are preprocessor constant expressions too, so #if works,
> - the second is already possible using generic lambdas (but it's a little hacky):
>   if_(b, [&](auto){ blah; }, [&](auto){ blah2; }) // implementation left as an exercise to the reader

Maybe I'm misunderstanding something, but when I as a reader tried your exercise, I failed
miserably at first:

#include <type_traits>

template <bool Expr_>
struct StaticIf {
        template <typename Code_>
        static void apply(Code_)
        {
        }
};

template <>
struct StaticIf<true> {
        template <typename Code_>
        static void apply(Code_ code)
        {
                code(1);
        }
};

template <bool Expr_, typename Code_>
void static_if(Code_ code)
{
        return StaticIf<Expr_>::apply(code);
}


template <typename T>
void foo(T t)
{
        // Call <t.bar> if <T> is a class
        static_if<std::is_class<T>::value>([&](auto) {
                t.bar();
        });
}

struct Bar {
        void bar() {}
};


int main()
{
        foo(1);
        foo(Bar{});
}


This does not compile as <t> inside the generic lambda is not a name dependent on the lambda's
template parameter and thus requires <T> to be a class with a method <bar>.

It is of course possible to make <t> artificially dependent on the lambda's template parameter,
e.g. by saying:

// Make T dependent on D
template <typename T, typename D>
T makeDependent(T t, D /*d*/)
{
        return t;
}

template <typename T>
void foo(T t)
{
        // Call <t.bar> if <T> is a class
        static_if<std::is_class<T>::value>([&](auto dummy) {
                auto t2 = makeDependent(t, dummy);
                t2.bar();
        });
}


This compiles, but IMO is really hacky and inelegant. Similar to local structs are inelegant
compared to lambdas.

Do you know of a more elegant way?


Jonathan

P.S: Correct forwarding of values left as an exercise to the reader ;-)


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev