取消引用空指针
int* p = 0;
int* q = &*p;
这是未定义的行为吗?我浏览了一些相关的问题,但这个具体方面没有出现。
int* p = 0;
int* q = &*p;
Is this undefined behavior or not? I browsed some related questions, but this specific aspect didn't show up.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个问题的答案是:这取决于您遵循哪种语言标准:-)。
在 C90 和 C++ 中,这是无效的,因为您对空指针执行间接寻址(通过执行
*p
),并且这样做会导致未定义的行为。然而,在 C99 中,这个是有效的、格式良好且定义良好的。在 C99 中,如果 unary-
&
的操作数是通过应用 unary-*
或执行下标 ([]
),则既不应用&
,也不应用*
或[]
。例如:同样,
来自 C99 §6.5.3.2/3:
(及其脚注,#84):
The answer to this question is: it depends which language standard you are following :-).
In C90 and C++, this is not valid because you perform indirection on the null pointer (by doing
*p
), and doing so results in undefined behavior.However, in C99, this is valid, well-formed, and well-defined. In C99, if the operand of the unary-
&
was obtained as the result of applying the unary-*
or by performing subscripting ([]
), then neither the&
nor the*
or[]
is applied. For example:Likewise,
From C99 §6.5.3.2/3:
(and its footnote, #84):
是的,这将是未定义的行为,但您的编译器可能会优化
&*
。为什么它是未定义的,是因为您正在尝试访问可寻址空间之外的内存。
Yes that would be undefined behavior, but your compiler might optimize the
&*
out.Why it its undefined, is that you are attempting to access memory outside your addressable space.
是的,取消引用空指针是未定义的行为。指针上下文中的整数常量 0 是空指针。就是这样。
现在,如果您的第二行是
int *q = p;
这将是一个简单的指针赋值。如果编译器删除了&*
并减少了对赋值的取消引用,那就没问题了。Yes, dereferencing the null pointer is undefined behavior. Integer constant 0 in a pointer context is the null pointer. That's it.
Now, if your second line was
int *q = p;
that would be a simple pointer assignment. If the compiler removes the&*
and reduces the dereference to an assignment, you're OK.恕我直言,就这两行代码而言,地址空间之外没有任何访问。第二条语句只是获取 (*p) 的地址,该地址又是“p”,因此它将存储“0”。但该位置永远不会被访问。
IMHO, As far as the two code lines are concerned, there isn't any access outside the address space. The second statement is simply taking the address of (*p) which would be 'p' again and hence it will store '0'. But the location is never accessed.