c++ - 空引用时的崩溃行为

标签 c++ reference nullreferenceexception

当错误的 C++ 代码尝试创建如下所示的空引用时:

int &ptr2ref(int *p){
    return *p;
}

int calc(int &v){
    return v*2;
}

...
int &i = ptr2ref(nullptr);
calc(i);

至少在 Visual C++ 中,它在函数 calc 的返回语句( Debug模式)中崩溃了。

然而,this question的答案报价

8.3.2/1:

A reference shall be initialized to refer to a valid object or function. [Note: in particular, 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. As described in 9.6, a reference cannot be bound directly to a bit-field. ]

1.9/4:

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer)

如果我没理解错的话,该标准表示,一旦创建了空引用,程序行为就未定义。 因此,如果编译器打算生成有用的调试信息,它应该在上面示例中的函数 ptr2ref 处崩溃,因为那里是创建空引用的地方(并且发生了引用) .

我错过了什么吗?是否有任何问题阻止编译器至少在 Debug模式下生成此类代码?

未定义的行为

我知道人们会争辩说“未定义”大致意味着一切。我的论点是,考虑到标准没有指定一个简单的 int main(){} 应该花费多长时间来编译,没有人会接受超过一天的编译时间。所以问题在于实现选项,而不是标准本身。 我在这里引用标准只是说在 ptr2ref 上崩溃是一个选项

此外,在 Debug模式下已经有很多额外的检查,例如,在从函数返回之前总是检查堆栈以查看是否有任何损坏。与那些相比,我认为添加一个相对简单的检查在 Debug模式中不会过于庞大。

最佳答案

“未定义的行为”并不意味着“立即崩溃”。

它在 C++ 标准中定义,第 1.3.24 节

Behavior for which this International Standard imposes no requirements

[ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.

  • 程序不需要在您绑定(bind)空引用后立即崩溃。
  • 让编译器生成代码来检查这些情况会给程序带来巨大的开销,这是 Not Acceptable 。

关于c++ - 空引用时的崩溃行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24794740/

相关文章:

c++ - 将成员函数指针作为模板参数传递

C++ static_cast 从 float** 到 void**

php - 奇怪的行为,通过引用分配 undefined variable

C# 输出参数与返回值

C# 检查属性的属性是否为 null 的优雅方法

c# - F# 与 C# 类互操作,该类具有一个可选的可空参数设置为除 null 之外的任何值会导致 NullReferenceException/AccessViolationException

c++ - stringstream object() 和 object 有什么区别?

c++ - 什么时候不调用重写的虚函数

c# - 我可以在Java中通过引用传递参数吗?

c# - 找不到为什么我有空引用异常