C预处理程序是否删除"*"的实例? [英] Does the C preprocessor remove instances of "&*"?

查看:116
本文介绍了C预处理程序是否删除"*"的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩gcc,并尝试了以下代码:

I was playing around with gcc and tried the following bit of code:

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

C == &A,与预期的一样.但是当我尝试:

And C == &A, as expected. But when I try:

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

结果为C == NULL,并且没有段错误.因此,&*B实际上并没有在获取其地址之前取消引用B.

Turns out C == NULL, and no segfault. So &*B is not actually dereferencing B before taking its address.

我的猜测是,预处理器正在将&**&的实例甚至在到达编译器之前就进行了剥离,因为它们彼此取反,但是我找不到任何文档来验证这是否是标准的 C 或特定于编译器.

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?

推荐答案

预处理器并没有将其删除,&*最终等同于指针本身,我们可以通过以下方法看到它: 草稿C99标准 6.5.3.2 地址和间接运算符 4 段,内容为:

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 standard 6.5.3.2 Address and indirection operators paragraph 4 which says:

一元*运算符表示间接.如果操作数指向一个函数,则结果为 功能指示符;如果它指向一个对象,则结果是一个左值,表示 目的.如果操作数的类型为要输入的指针",则结果的类型为类型".如果 无效的值已分配给指针,一元*运算符的行为是 未定义. 87)

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是空指针),[...]

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

和第 3 段说(强调我的):

一元&运算符产生其操作数的地址.如果操作数的类型为"type", 结果的类型为要输入的指针". 如果操作数是一元*运算符的结果, 该运算符和&对运算符进行评估,结果就好像两个都 省略,只是对运算符的约束仍然适用,并且结果不是左值.

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.

更新

可能值得一提的是,对于gccclang,您可以使用-E标志( /EP ( 实时查看 ).

It is probably worth it to note that for gcc and clang you can view the results of pre-processing by using the -E flag(see it live) and in Visual Studio /EP(see it live).

另外,值得注意的是,正如MSalters在其评论中所说,仅具有两个标记&*不足以理解上下文,如他的示例所示:

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:

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

因此在预处理阶段甚至无法删除&*,因为您将没有足够的信息来确定&运算符的地址还是按位和运算符.

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.

这篇关于C预处理程序是否删除"*"的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆