我在玩耍gcc
并尝试了以下代码:
int A = 42;
int *B = &A;
int *C = &*B;
和C == &A
,正如预期的那样。但是当我尝试:
int *B = NULL;
int *C = &*B;
事实证明C == NULL
,没有段错误。因此在获取地址之前&*B
实际上并没有取消引用B
。
我的猜测是预处理器剥离出来的情况下,&*
和*&
之前,他们甚至得到了编译器,因为他们否定对方,但我无法找到任何文件,以验证这是否是标准ç或编译器特定的。
预处理程序是否去除了&*
和*&
,我可以从任何给定的编译器获得这种行为吗?
预处理器并没有剥离它,&*
只是最终等同于指针本身,我们可以通过起草C99标准 6.5.3.2
地址和间接操作符第4段来看到这一点,该段说:
一元*运算符表示间接。如果操作数指向一个函数,则结果为一个函数指示符;否则为0。如果它指向一个对象,则结果是一个指定该对象的左值。如果操作数的类型为“类型的指针”,则结果的类型为“ type”。如果为指针分配了无效值,则一元*运算符的行为是不确定的。87)
脚注87说:
因此,&* E等于E(即使E是空指针),[...]
第3段说(重点是我的):
一元&运算符产生其操作数的地址。如果操作数的类型为“类型”,则结果的类型为“类型的指针”。如果操作数是一元*运算符的结果,则不会对该运算符和&运算符求值,并且结果都好像都被省略了,除了运算符上的约束仍然适用并且结果不是左值。
更新资料
值得一提的是gcc
,clang
您可以使用-E
flag(实时查看)和Visual Studio / EP(实时查看)查看预处理结果。
另外,值得注意的是,正如MSalters在他的评论中所说,仅仅拥有两个标记&*
不足以理解上下文,如他的示例所示:
int *p, *q ;
int foo = *p & *q ;
因此&*
,在预处理阶段甚至无法删除,因为您将没有足够的信息来确定操作符&
的地址还是按位运算符的地址。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句