当错误的 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/