I was playing around with gcc
and tried the following bit of code:
int A = 42;
int *B = &A;
int *C = &*B;
And C == &A
, as expected. But when I try:
int *B = NULL;
int *C = &*B;
Turns out C == NULL
, and no segfault. So &*B
is not actually dereferencing B
before taking its address.
My guess is that the preprocessor is stripping out instances of &*
and *&
before they even get to the compiler since they negate each other, but I can't find any documentation to verify whether this is standard C or compiler-specific.
Is the preprocessor stripping out &*
and *&
, and can I expect this behavior from any given compiler?
The preprocessor does not elide
&*
. However, the C 2011 standard says in 6.5.3.2 3, about&
:As required by the constraints mentioned above, the operand of * must have pointer type. Thus,
&*3
is not changed to3
by this clause; it violates the constraints because3
does not have pointer type. Additionally,&*x
is not quite changed tox
, since the result is not an lvalue. For example, this is not allowed:This is not being stripped out by the the pre-procesor,
&*
just ends up being equivalent to the pointer itself, we can see this by going to draft C99 standard6.5.3.2
Address and indirection operators paragraph 4 which says:and footnote 87 says:
and paragraph 3 says (emphasis mine):
Update
It is probably worth it to note that for
gcc
andclang
you can view the results of pre-processing by using the-E
flag(see it live) and in Visual Studio /EP(see it live).Also, worth noting that as MSalters said in his comment just having the two tokens
&*
is not sufficient to understand the context, as his example shows:So just removing
&*
would not even be possible during the pre-processing stage since you would not have sufficient information available to determine whether&
was the address of operator or bitwise and operator.