c++ - 为什么 'undefined behaviour'存在?

标签 c++ c compiler-errors compilation undefined-behavior

<分区>

某些常见的编程语言,尤其是 C 和 C++,具有强烈的未定义行为概念:当您尝试执行超出预期使用方式的某些操作时,这会导致未定义行为。

如果发生未定义的行为,编译器可以做它想做的任何事情(包括什么都不做,“时间旅行”等)。

我的问题是:为什么存在这种未定义行为的概念?据我所知,如果不是导致未定义的行为,而是使用其预期用途之外的操作会导致大量错误,一个版本的编译器停止工作的程序停止在下一个版本的编译器上工作等,将被阻止编译错误

为什么事情不是这样的?

最佳答案

Why does this notion of undefined behaviour exist?

允许语言/库尽可能高效地在各种不同的计算机体系结构上实现(- 可能在 C 的情况下 - 同时允许实现保持简单)。

if instead of causing undefined behaviour, using the operations outside of their intended use would cause a compilation error

在大多数未定义行为的情况下,一般来说,要证明所有程序在编译时都存在未定义行为是不可能的,或者在资源上非常昂贵。

一些 案例可以证明一些 程序,但不可能指定哪些案例是详尽无遗的,因此标准不会尝试这样做所以。尽管如此,一些编译器足够聪明,可以识别一些简单的 UB 情况,并且这些编译器会警告程序员。示例:

int arr[10];
return arr[10];

这个程序有未定义的行为。我测试的特定版本的 GCC 显示:

warning: array subscript 10 is above array bounds of 'int [10]' [-Warray-bounds]

忽略这样的警告可不是什么好主意。


具有未定义行为的更典型的替代方法是在这种情况下定义错误处理,例如抛出异常(例如比较 Java,其中访问空引用会导致 java.lang.NullPointerException 类型的异常 被抛出)。但是检查明确定义的行为的先决条件比不检查要慢。

通过不检查前置条件,该语言为程序员提供了自行证明正确性的选项,从而避免了在已证明不需要的程序中进行检查的运行时开销。事实上,这种力量伴随着巨大的责任。

如今,使用工具 (example) 可以在一定程度上减轻证明程序定义良好的负担,这些工具添加了一些运行时检查,并在检查失败时巧妙地终止程序。

关于c++ - 为什么 'undefined behaviour'存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51557895/

相关文章:

c++ - 从 Eclipse IDE 运行 C 程序时如何为其指定命令行参数

Java初学者,类构造函数错误,找不到参数

angular - typescript 错误 : TS2314: Generic type 'ElementRef<T, any>' requires 2 type argument(s)

c++ - shared_ptr 的复制分配导致段错误?

c++ - 如何最好地定义/构造/初始化 std::string 包装类

c++ - 如何将函数标记为使其参数无效

c - 阅读总是比要求的少读八位字节

c - 如何在 Brew 上检测手机品牌和型号信息?

c - OpenMP 中的 C 指针

java - 格式转换出现问题,出现奇怪的错误