c++ - 在什么时候取消引用空指针会变成未定义的行为?

标签 c++ object null undefined-behavior dereference

如果我实际上没有访问取消引用的“对象”,取消引用空指针是否仍然未定义?

int* p = 0;
int& r = *p;    // undefined?
int* q = &*p;   // undefined?

一个稍微更实际的例子:我可以取消引用空指针来区分重载吗?

void foo(Bar&);
void foo(Baz&);

foo(*(Bar*)0);  // undefined?

好的,根据标准,引用示例肯定是未定义的行为:

a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the "object" obtained by dereferencing a null pointer, which causes undefined behavior.

不幸的是,强调的部分是模棱两可的。是绑定(bind)部分导致了未定义的行为,还是解引用部分就足够了?

最佳答案

我认为What every C programmer should know about Undefined Behavior的第二部作品|可能有助于说明这个问题。

以博客为例:

void contains_null_check(int *P) {
  int dead = *P;
  if (P == 0)
    return;
  *P = 4;
}

可能被优化为(RNCE:冗余空检查消除):

void contains_null_check_after_RNCE(int *P) {
  int dead = *P;
  if (false)  // P was dereferenced by this point, so it can't be null 
    return;
  *P = 4;
}

优化后变成(DCE: Dead Code Elimination):

void contains_null_check_after_RNCE_and_DCE(int *P) {
  //int dead = *P; -- dead store
  //if (false)     -- unreachable branch
  //  return;
  *P = 4;
}

如您所见,即使 dead 从未 使用过,简单的 int dead = *P 赋值已导致未定义行为蔓延在程序中。

为了区分重载,我建议使用指针(可能为 null),而不是人为地创建一个 null 引用并将自己暴露给未定义的行为。

关于c++ - 在什么时候取消引用空指针会变成未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7130878/

相关文章:

android - Qt5 QGeoPositionInfoSource::createDefaultSource() 在 Android 5.0 上崩溃

c++ - 无法在 Metro Style Project (WINRT) 中使用 opencl

javascript - 为什么重新分配 Object.prototype 不起作用?

scala - val 和单例对象之间的细微差别是什么?

ios - 如何访问对象的恢复 ID(为什么为空?)

MySQL:JOIN 查询获取所有具有可为空字段的项目

c++ - 对SFINAE使用void_t中带有参数的方法

c++ - 是否有任何交互式控制台 B-Tree 实现?

javascript - 获取数组内的对象

c - 如果有人没有写任何东西就进入然后它应该终止