这并没有被预处理器剥离,&*
只是最终等同于指针本身,我们可以通过草拟 C99 标准 6.5.3.2
地址和间接运算符第4段来看到这一点,其中说:
一元 * 运算符表示间接。如果操作数指向一个函数,则结果是一个函数指示符;如果它指向一个对象,则结果是一个指定该对象的左值。如果操作数的类型为 ''pointer to type'',则结果的类型为 ''type''。如果已为指针分配了无效值,则一元 * 运算符的行为未定义。87)
脚注 87 说:
因此,&*E 等价于 E(即使 E 是空指针),[...]
第3段说(强调我的):
一元 & 运算符产生其操作数的地址。如果操作数的类型为“type”,则结果的类型为“pointer to type”。如果操作数是一元 * 运算符的结果,则该运算符和 & 运算符都不会被计算,结果就像两者都被省略了一样,除了对运算符的约束仍然适用并且结果不是左值。
更新
值得注意的是gcc
,您可以使用标志(实时查看)和 Visual Studio /EP(实时查看clang
)查看预处理结果。-E
此外,值得注意的是,正如 MSalters 在他的评论中所说,仅拥有两个标记&*
不足以理解上下文,如他的示例所示:
int *p, *q ;
int foo = *p & *q ;
&*
因此,在预处理阶段甚至不可能仅删除,因为您没有足够的信息来确定&
是运算符的地址还是按位和运算符的地址。