gpt4 book ai didi

c++ - 未定义、未指定和实现定义的行为

转载 作者:bug小助手 更新时间:2023-10-28 01:30:37 26 4
gpt4 key购买 nike

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

最佳答案

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

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

#include <iostream>

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

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

The effect of attempting to modify a string literal is undefined.

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

未定义行为的其他示例包括访问超出其边界的数组,dereferencing the null pointer , accessing objects after their lifetime ended或写 allegedly clever expressions比如 i+++++i.

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

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine.

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 节规定:

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).

您可以做些什么来避免遇到未定义的行为?基本上,你必须阅读 good C++ books作者知道他们在说什么。避免使用互联网教程。避免bullschildt。

关于c++ - 未定义、未指定和实现定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2397984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com