celliso2 at illinois.edu
Tue Jan 17 17:25:40 CST 2012
There is an interesting little exception in the semantics of & if the
operand is a deref (*). The C11 (and C99) standards say (188.8.131.52)
"the result is as if both were omitted, except that the constraints on
the operators still apply and the result is not an lvalue".
Essentially, for E of pointer type, &*E is equivalent to E, even if E
is a null pointer.
I was writing some tests for this for kcc and hit on the following expression:
&(&(*(*(void**)NULL))) == (void**)NULL
I'd argue that based on the standard, &(&(*(*(void**)NULL))) is "as
if" it were &(*(void**)NULL), which is "as if" it were (void**)NULL.
It seems to me that this expression is defined and is true. However,
GCC (4.1.2) and Clang (3.0 (trunk 132915)) don't seem to handle this
case. GCC gives "error: invalid lvalue in unary '&'" and Clang gives
"error: address expression must be an lvalue or a function
designator". I think these are both incorrect errors, because the
constraints for the & operator allow another case:
(184.108.40.206:1) "The operand of the unary & operator shall be either a
function designator, the result of a  or unary * operator, or an
lvalue that designates an object". GCC and Clang don't seem to
support the case "the result of a  or unary * operator".
For what it's worth, ICC (11.1) accepts the expression with no
warnings and evaluates to true.
What do you all think about this example? Do more recent versions of
GCC run it?
More information about the c-semantics