<div class="gmail_quote">On Mon, Aug 16, 2010 at 1:42 AM, Abramo Bagnara <span dir="ltr"><<a href="mailto:abramo.bagnara@gmail.com">abramo.bagnara@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Il 16/08/2010 10:22, Chandler Carruth ha scritto:<br>
<div class="im">> On Mon, Aug 16, 2010 at 12:31 AM, Abramo Bagnara<br>
</div><div><div></div><div class="h5">> <<a href="mailto:abramo.bagnara@gmail.com">abramo.bagnara@gmail.com</a> <mailto:<a href="mailto:abramo.bagnara@gmail.com">abramo.bagnara@gmail.com</a>>> wrote:<br>
><br>
><br>
>     The following typescript show the issue:<br>
><br>
>     $ cat t.cc<br>
><br>
>     template <int *ptr><br>
>     struct S1 { };<br>
><br>
>     template <bool b><br>
>     struct S2 { };<br>
><br>
>     int v1;<br>
><br>
>     S1<(&v1)> x;<br>
>     S2<(2>2)> y;<br>
>     $ clang -c t.cc<br>
>     t.cc:10:4: error: non-type template argument cannot be surrounded by<br>
>     parentheses<br>
>     S1<(&v1)> x;<br>
>       ^~~~~<br>
>     1 error generated.<br>
><br>
>     My notes:<br>
><br>
>     1) in my opinion the diagnostic is due to a needless too strong<br>
>     interpretation of the standard:<br>
><br>
>     - comeau and intel does not mark this as an error<br>
><br>
>     - gcc seems to mark this as an error due to some bug (the diagnostic  is<br>
>     very weird)<br>
><br>
><br>
> The standard seems really really clear here -- the argument is *not* an<br>
> expression, it's an address. You're only provided one mechanism for<br>
> writing an address in this context: '& id-expression', with the '&'<br>
> being optional in certain cases. You can't even write '0' here. I think<br>
> it's actually useful to preclude parentheses as they make this look like<br>
> an expression, which it simply is not. You can't write '(&foo +<br>
> sizeof(int))' to advance past one element of an int array either.<br>
><br>
<br>
</div></div>Hmmm... perhaps not so clear...<br>
<br>
If you look at standard grammar, you read this:<br>
<br>
template-argument:<br>
  constant-expression<br>
  type-id<br>
  id-expression<br>
<br>
Of course S1<v1> is in the 'id-expression' case, but both S1<&v1> and<br>
S1<(&v1)> are in 'constant-expression' case.<br>
<br>
Don't you think that if the intention was to inhibit parenthesis use the<br>
standard would have been written as:<br>
<br>
template-argument:<br>
  constant-expression<br>
  type-id<br>
  '&'opt id-expression<br>
<br>
?<br>
</blockquote></div><br><div>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:</div>
— 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<br>— a constant expression that evaluates to a null pointer value (4.10); or<br>
— a constant expression that evaluates to a null member pointer value (4.11); or<div><br></div><div>That's it. The only way you get an address of an actual object is:</div><div>— 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</div>
<div><br></div><div>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.</div><div>
<br></div>