以下哪个会创建空指针?

big*_*g-z 14 c++ null-pointer dereference

标准说,取消引用空指针会导致未定义的行为.但是什么是"空指针"?在下面的代码中,我们称之为"空指针":

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)
}
Run Code Online (Sandbox Code Playgroud)

我的想法是,只有在最后一种情况下才会取消引用空指针.我对吗?根据C++标准,编译时空指针和运行时之间是否存在差异?

Joh*_*itb 12

只有第一个和最后一个是空指针.其他是结果,reinterpret_cast因此对实现定义的指针值进行操作.是否为它们定义了行为取决于您转换到的地址是否有对象.

  • @Scott Smith:它是实现定义的.特别是在没有"核心"概念的平台上,即UNIX之外的任何东西. (2认同)

Mar*_*ers 12

求值为0的整型常量表达式作为空指针有效,因此第一种情况也是取消引用空指针.

通过某种算术计算设置为0的指针不一定是空指针.在大多数实现中,它的行为方式与空指针相同,但标准不保证这一点.

  • @詹姆斯啊!所以0!= NULL表示非常大的0! (2认同)

Ale*_*tov 7

C++标准(2003)4.10

4.10指针转换

1空指针常量是整数类型的整数常量表达式(5.19)rvalue,其值为零.空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与指向对象的指针或指向函数类型的指针的每个其他值区分开来.相同类型的两个空指针值应相等.将空指针常量转换为指向cv限定类型的指针是单个转换,而不是指针转换的序列,后跟限定转换(4.4).

5.2.10重新解释演员

注64)用值零转换整数常量表达式(5.19)总是产生一个空指针(4.10),但是转换其它值恰好为零的表达式不需要产生空指针.

1) X* x = 0; (*x).f();是的.0是整数常量表达式,并转换为空指针常量.然后空指针常量可以转换为空指针值.

2)x = X::get();否,见5.2.10中的注释64

3)x = reinterpret_cast<X*>( X::get() - X::get() );否,见5.2.10中的注释64

4)((X)0).f(); 是.0(整数常量表达式) - >空指针常量 - >空指针值.