C预处理器删除“&*”的实例吗?

我正在玩gcc并尝试下面的代码:

int A = 42;
int *B = &A;
int *C = &*B;

和C ==& A,如预期。但是当我尝试:

int *B = NULL;
int *C = &*B;

结果是C == NULL,没有segfault。所以& * B实际上并没有取消引用B的地址。

我的猜测是,预处理器剥离了& *和*&在他们甚至得到编译器,因为他们互相否定,但我找不到任何文档,以验证这是标准C还是编译器特定的。

是预处理器剥离& *和*&,和我可以期望这种行为从任何给定的编译器?

最佳答案
这不是被前处理器剥离,&*只是最终等于指针本身,我们可以看到这通过去draft C99 standard 6.5.3.2地址和间接操作符第4段说:

The unary * operator denotes indirection. If the operand points to a function, the result is
a function designator; if it points to an object, the result is an lvalue designating the
object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
invalid value has been assigned to the pointer, the behavior of the unary * operator is
undefined.87)

和脚注87说:

Thus, &*E is equivalent to E (even if E is a null pointer),[…]

第3段说(强调我):

The unary & operator yields the address of its operand. If the operand has type ‘‘type’’,
the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator,
neither that operator nor the & operator is evaluated and the result is as if both were
omitted
, except that the constraints on the operators still apply and the result is not an lvalue.

更新

可能值得注意的是,对于gcc和clang,您可以使用-E标志(see it live)和Visual Studio /EP(see it live)查看预处理的结果。

另外,值得注意的是,MSalters在他的评论中说,只是拥有两个令牌并不足以理解上下文,如他的例子所示:

int *p, *q ;
int foo = *p & *q ;

所以只是在预处理阶段甚至不可能删除& *,因为你不会有足够的信息来确定&是运算符的地址或按位和运算符。

转载注明原文:C预处理器删除“&*”的实例吗? - 代码日志