https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67064

hannes_weisbach at gmx dot net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hannes_weisbach at gmx dot net

--- Comment #4 from hannes_weisbach at gmx dot net ---
Hi,

I've read the bug report and dug into the standards. This is my understanding
of the issue(s):

Quoting N3337 and N3797 (C++11 & 14 Standard Drafts) §7.1.1/2 (dcl.stc):
"The register specifier shall be applied only to names of variables declared in
a block (6.3) or to function parameters (8.4)."

So gcc should reject the declaration of 'reg' outright, since it is not
declared inside a block and 'reg' is not a function parameter.

If 'reg' would be properly declared, namely in block scope, the note (though
non-normative) in §7.1.1/3 (dcl.stc) is interesting:
"The hint can be ignored and in most implementations it will be ignored if the
address of the variable is taken." (Which is the case by enclosing it in
braces, see below.)

As for the type of '(expression)' §5.1.1/6 (expr.prim.general) says:
"A parenthesized expression is a primary expression whose type and value are
identical to those of the enclosed expression. The presence of parentheses does
not affect whether the expression is an lvalue. The parenthesized expression
can be used in exactly the same contexts as those where the enclosed expression
can be used, and with the same meaning, except as otherwise indicated."

So clearly, parenthesis should not change the type, but both clang (Apple LLVM
version 6.1.0 (clang-602.0.53)) and gcc (gcc version 5.1.0 (Homebrew gcc
5.1.0)) do. Given the declaration of 'struct s' from the example, and a
definition of 'struct s * reg;' (to avoid the register thing) the type of 'reg'
is 's*', but the type of '(reg)' is 's*&'. Since now there is a reference to
'reg', its address has been taken.

OTOH, §7.1.6.2/4 says that, if e is an parenthesized expression with type T,
decltype(e) is T&. I would expect the type of 'reg' being different from
'(reg)' only in a decltype-specifier and not otherwise.

Maybe someone can explain why the decltype-rule for (the type of) parenthesized
expression is applicable without the decltype-specifier there. I hope the
language-lawyering brought at least some clarity.

Reply via email to