[cfe-dev] Weird diagnostic about non-type template argument

Chandler Carruth chandlerc at google.com
Mon Aug 16 01:57:19 PDT 2010


On Mon, Aug 16, 2010 at 1:55 AM, Chandler Carruth <chandlerc at google.com>wrote:

> On Mon, Aug 16, 2010 at 1:42 AM, Abramo Bagnara <abramo.bagnara at gmail.com>wrote:
>
>> Il 16/08/2010 10:22, Chandler Carruth ha scritto:
>> > On Mon, Aug 16, 2010 at 12:31 AM, Abramo Bagnara
>> > <abramo.bagnara at gmail.com <mailto:abramo.bagnara at gmail.com>> wrote:
>> >
>> >
>> >     The following typescript show the issue:
>> >
>> >     $ cat t.cc
>> >
>> >     template <int *ptr>
>> >     struct S1 { };
>> >
>> >     template <bool b>
>> >     struct S2 { };
>> >
>> >     int v1;
>> >
>> >     S1<(&v1)> x;
>> >     S2<(2>2)> y;
>> >     $ clang -c t.cc
>> >     t.cc:10:4: error: non-type template argument cannot be surrounded by
>> >     parentheses
>> >     S1<(&v1)> x;
>> >       ^~~~~
>> >     1 error generated.
>> >
>> >     My notes:
>> >
>> >     1) in my opinion the diagnostic is due to a needless too strong
>> >     interpretation of the standard:
>> >
>> >     - comeau and intel does not mark this as an error
>> >
>> >     - gcc seems to mark this as an error due to some bug (the diagnostic
>>  is
>> >     very weird)
>> >
>> >
>> > The standard seems really really clear here -- the argument is *not* an
>> > expression, it's an address. You're only provided one mechanism for
>> > writing an address in this context: '& id-expression', with the '&'
>> > being optional in certain cases. You can't even write '0' here. I think
>> > it's actually useful to preclude parentheses as they make this look like
>> > an expression, which it simply is not. You can't write '(&foo +
>> > sizeof(int))' to advance past one element of an int array either.
>> >
>>
>> Hmmm... perhaps not so clear...
>>
>> If you look at standard grammar, you read this:
>>
>> template-argument:
>>  constant-expression
>>  type-id
>>  id-expression
>>
>> Of course S1<v1> is in the 'id-expression' case, but both S1<&v1> and
>> S1<(&v1)> are in 'constant-expression' case.
>>
>> Don't you think that if the intention was to inhibit parenthesis use the
>> standard would have been written as:
>>
>> template-argument:
>>  constant-expression
>>  type-id
>>  '&'opt id-expression
>>
>> ?
>>
>
> No, because the general grammar is not meant to be normative. You can't
> read one piece of grammar and know what is or is not a valid program. In
> this case, you're citing text from 14.2 (C++0x rather than '03, but I'll
> stick with '0x for now -- if anything '03 is *more* restrictive here!), but
> the detail of what goes into a template argument is more fully explained by
> 14.3.2 [template.arg.nontype]. Here, it clearly lists what
> constant-expression arguments are allowed:
> — an integral constant expression (including a constant expression of
> literal class type that can be used as an integral constant expression as
> described in 5.19); or
> — a constant expression that evaluates to a null pointer value (4.10); or
> — a constant expression that evaluates to a null member pointer value
> (4.11); or


For reference, these two are what are missing in C++03. In '03 you can't
even write '0' as a template argument for a pointer non-type template
argument. In '0x, you can, you can even write a complex const-expr to do so.
But you can't make it evaluate to any other pointer value, for that you have
to use the rule below.


>
> That's it. The only way you get an address of an actual object is:
> — the address of an object or function with external linkage, including
> function templates and function template-ids but excluding non-static class
> members, expressed as & id-expression where the & is optional if the name
> refers to a function or array, or if the corresponding template-parameter is
> a reference
>
> This is very clear that it is *restricting* the syntax allowed to represent
> the address of an object. It seems to specifically preclude pointer
> arithmetic and other expressions on the address.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100816/806a6aa6/attachment.html>


More information about the cfe-dev mailing list