本文介绍了未定义、未指定和实现定义的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是 C 和 C++ 中的未定义行为 (UB)?未指定的行为实现定义的行为呢?它们有什么区别?

What is undefined behavior (UB) in C and C++? What about unspecified behavior and implementation-defined behavior? What is the difference between them?

推荐答案

未定义行为 是 C 和 C++ 语言中令程序员感到惊讶的方面之一来自其他语言(其他语言试图更好地隐藏它).基本上,即使许多 C++ 编译器不会报告程序中的任何错误,也可以编写不以可预测方式运行的 C++ 程序!

Undefined behavior is one of those aspects of the C and C++ language that can be surprising to programmers coming from other languages (other languages try to hide it better). Basically, it is possible to write C++ programs that do not behave in a predictable way, even though many C++ compilers will not report any errors in the program!

我们来看一个经典的例子:

Let's look at a classic example:

#include <iostream>

int main()
{
    char* p = "hello!
";   // yes I know, deprecated conversion
    p[0] = 'y';
    p[5] = 'w';
    std::cout << p;
}

变量 p 指向字符串文字 "hello!",下面的两个赋值尝试修改该字符串文字.这个程序有什么作用?根据 C++ 标准的第 2.14.5 节第 11 段,它调用了未定义行为:

The variable p points to the string literal "hello!", and the two assignments below try to modify that string literal. What does this program do? According to section 2.14.5 paragraph 11 of the C++ standard, it invokes undefined behavior:

尝试修改字符串文字的效果未定义.

我可以听到人们在尖叫但是等等,我可以毫无问题地编译它并获得输出yellow";或您是什么意思未定义,字符串文字存储在只读内存中,因此第一次分配尝试会导致核心转储".这正是未定义行为的问题.基本上,一旦您调用未定义的行为(甚至是鼻恶魔),该标准就会允许任何事情发生.如果有一个正确"根据您对语言的心理模型的行为,该模型完全是错误的;C++ 标准拥有唯一的投票权,句号.

I can hear people screaming "But wait, I can compile this no problem and get the output yellow" or "What do you mean undefined, string literals are stored in read-only memory, so the first assignment attempt results in a core dump". This is exactly the problem with undefined behavior. Basically, the standard allows anything to happen once you invoke undefined behavior (even nasal demons). If there is a "correct" behavior according to your mental model of the language, that model is simply wrong; The C++ standard has the only vote, period.

未定义行为的其他示例包括访问超出其边界的数组、取消引用空指针在对象生命周期结束后访问对象 或编写据称是聪明的表达式,例如i++ + ++i.

Other examples of undefined behavior include accessing an array beyond its bounds, dereferencing the null pointer, accessing objects after their lifetime ended or writing allegedly clever expressions like i++ + ++i.

C++ 标准的第 1.9 节还提到了未定义行为的两个不太危险的兄弟,未指定行为实现定义的行为:

Section 1.9 of the C++ standard also mentions undefined behavior's two less dangerous brothers, unspecified behavior and implementation-defined behavior:

本国际标准中的语义描述定义了一个参数化的非确定性抽象机器.

抽象机的某些方面和操作在本国际标准中被描述为实现定义(例如,sizeof(int)).这些构成了抽象机的参数.每个实现都应包含描述其在这些方面的特征和行为的文档.

Certain aspects and operations of the abstract machine are described in this International Standard as implementation-defined (for example, sizeof(int)). These constitute the parameters of the abstract machine. Each implementation shall include documentation describing its characteristics and behavior in these respects.

抽象机的某些其他方面和操作在本国际标准中被描述为未指定(例如,函数参数的求值顺序).在可能的情况下,本国际标准定义了一组允许的行为.这些定义了抽象机器的不确定性方面.

Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, order of evaluation of arguments to a function). Where possible, this International Standard defines a set of allowable behaviors. These define the nondeterministic aspects of the abstract machine.

本国际标准中将某些其他操作描述为未定义(例如,取消引用空指针的效果).[ 注意:本国际标准对包含未定义行为的程序的行为没有要求.尾注 ]

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [ Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior.end note ]

具体而言,第 1.3.24 节规定:

Specifically, section 1.3.24 states:

允许的未定义行为范围从完全无视情况并产生不可预测的结果,在翻译或程序执行期间以环境特征的记录方式行为(有或没有发布诊断消息),终止翻译或执行(发出诊断消息).

你能做些什么来避免遇到未定义的行为?基本上,您必须阅读了解自己在说什么的作者的优秀的 C++ 书籍.避免网络教程.避免废话.

What can you do to avoid running into undefined behavior? Basically, you have to read good C++ books by authors who know what they're talking about. Avoid internet tutorials. Avoid bullschildt.

这篇关于未定义、未指定和实现定义的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 21:42