其中哪一个会创建空指针?
该标准规定取消引用空指针会导致未定义的行为。但什么是“空指针”?在下面的代码中,我们称之为“空指针”:
struct X
{
static X* get() { return reinterpret_cast<X*>(1); }
void f() { }
};
int main()
{
X* x = 0;
(*x).f(); // the null pointer? (1)
x = X::get();
(*x).f(); // the null pointer? (2)
x = reinterpret_cast<X*>( X::get() - X::get() );
(*x).f(); // the null pointer? (3)
(*(X*)0).f(); // I think that this the only null pointer here (4)
}
我的想法是,空指针的取消引用仅发生在最后一种情况下。我说得对吗?根据 C++ 标准,编译时空指针和运行时之间有区别吗?
The standard says that dereferencing the null pointer leads to undefined behaviour. But what is "the null pointer"? In the following code, what we call "the null pointer":
struct X
{
static X* get() { return reinterpret_cast<X*>(1); }
void f() { }
};
int main()
{
X* x = 0;
(*x).f(); // the null pointer? (1)
x = X::get();
(*x).f(); // the null pointer? (2)
x = reinterpret_cast<X*>( X::get() - X::get() );
(*x).f(); // the null pointer? (3)
(*(X*)0).f(); // I think that this the only null pointer here (4)
}
My thought is that dereferencing of the null pointer takes place only in the last case. Am I right? Is there difference between compile time null pointers and runtime according to C++ Standard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只有第一个和最后一个是空指针。其他的是
reinterpret_cast
的结果,因此对实现定义的指针值进行操作。它们的行为是否未定义取决于您转换到的地址是否有对象。Only the first and the last are null pointers. The others are results of
reinterpret_cast
and thus operate on implementation defined pointer values. Whether the behavior is undefined for them depends on whether there is an object at the address you casted to.计算结果为 0 的整数常量表达式作为空指针是有效的,因此第一种情况也是取消引用空指针。
通过某些算术计算设置为 0 的指针不一定是空指针。在大多数实现中,它的行为方式与空指针相同,但标准不保证这一点。
An integer constant expression that evaluates to 0 is valid as a null pointer, so the first case is also dereferencing a null pointer.
A pointer which is set to 0 via some arithmetic calculation is not necessarily a null pointer. In most implementations it will behave in the same way as a null pointer, but this is not guaranteed by the standard.
C++ 标准 (2003) 4.10
4.10 指针转换
5.2.10 重新诠释演员阵容
1) X* x = 0; (*x).f(); 是的。
0 是整型常量表达式,转换为空指针常量。
然后可以将空指针常量转换为空指针值。
2)
x = X::get();
否,参见 5.2.10 中的注释 643)
x = reinterpret_cast( X::get() - X: :get() );
否,参见 5.2.10 中的注释 644) ((X)0).f();是的。
0(积分常量表达式)-->空指针常量 -->
空指针值。
C++ Standard (2003) 4.10
4.10 Pointer conversions
5.2.10 Reinterpret cast
1)
X* x = 0; (*x).f();
Yes.0 is integral constant expression and is converted to the null pointer constant.
Then null pointer constant can be converted to the null pointer value.
2)
x = X::get();
no, see note 64 in 5.2.103)
x = reinterpret_cast<X*>( X::get() - X::get() );
no, see note 64 in 5.2.104) ((X)0).f(); Yes.
0 (integral constant expression) --> the null pointer constant -->
the null pointer value.
我认为这符合解除引用的资格,即使
f()
从未实际使用this
指针,并且X
中没有虚拟方法。我的本能反应是这是一次崩溃,但现在想起来,我不太确定。可能是一个无效的指针。不确定它是否会崩溃(推理见上文)。
表达式
X::get() - X::get()
是否可以编译?我认为像这样从另一个指针中减去一个指针是不合法的。编辑:哦!当然是合法的。我在想什么?显然,我是栗色的。
I think this qualifies as dereference, even though
f()
never actually uses thethis
pointer, and there are no virtual methods inX
. My reflex was to say that this is a crash, but now that I think of it, I'm not so sure.Probably an invalid pointer. not sure whether it will crash (see above for reasoning).
Does the expression
X::get() - X::get()
compile? I didn't think it was legal to subtract a pointer from another pointer like that.EDIT: D'oh! Of course it's legal. What was I thinking? Clearly, I am a maroon.