我正在玩gcc
并尝试了以下代码:
int A = 42;
int *B = &A;
int *C = &*B;
And C == &A
,正如预期的那样。但是当我尝试时:
int *B = NULL;
int *C = &*B;
事实证明C == NULL
,并且没有段错误。所以&*B
实际上并没有解除引用B
在获取其地址之前。
我的猜测是预处理器正在剥离实例&*
and *&
在他们到达编译器之前,因为他们互相否定,但我找不到任何文档来验证这是否是标准的C或编译器特定的。
预处理器是否剥离&*
and *&
,我可以期待任何给定编译器的这种行为吗?
这并没有被预处理器剥离,&*
最终等同于指针本身,我们可以通过以下方式看到这一点C99标准草案 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf 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 说:
因此,&*E 等价于 E(即使 E 是空指针),[...]
和段落3 says (强调我的):
一元 & 运算符产生其操作数的地址。如果操作数的类型为“type”,
结果的类型为“指向类型的指针”。如果操作数是一元 * 运算符的结果,
该运算符和 & 运算符都不会被求值,结果就像两者都被计算一样
省略,除了对运算符的约束仍然适用并且结果不是左值。
Update
可能值得注意的是,对于gcc
and clang
您可以使用以下命令查看预处理结果-E
flag(现场观看 http://coliru.stacked-crooked.com/a/14c59c3b82357c73)以及在 Visual Studio 中/EP https://stackoverflow.com/questions/277258/c-c-source-file-after-preprocessing(现场观看 http://rextester.com/MYBJJ6088).
另外,值得注意的是,正如 MSalters 在他的评论中所说,只有两个令牌&*
不足以理解上下文,如他的示例所示:
int *p, *q ;
int foo = *p & *q ;
所以只需删除&*
在预处理阶段甚至不可能,因为您没有足够的信息来确定是否&
是地址运算符或按位和操作员。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)