为什么这句话:"未定义的行为意味着编译器可以做任何想做的事情"是真的吗?

Yva*_*ain 6 c++ compiler-construction undefined-behavior

具体参考:https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p = 633 /

我是一名新的C++程序员,我目前正在学习未定义的行为及其对程序的影响.我特意链接到上面的博客,该博客说当发生未定义的行为时,任何事情都可能发生.

它特别提到了几次,当发生未定义的行为时,编译器可以允许任何事情发生.

具体是什么导致这种情况发生,为什么会发生?

Lig*_*ica 19

什么都没有"导致"这种情况发生.未定义的行为不会"发生".没有神秘的力量落在你的电脑上,突然间它会在猫的内部产生黑洞.

当你运行一个行为未定义的程序时,任何事情都会发生,这是C++标准的事实.这是一个余地的陈述,是编译器用来对代码做出假设的一个方便的借口,以便提供有用的优化.

例如,如果我们说解除引用nullptr是未定义的(它是),那么没有编译器需要检查指针是不是nullptr:它可以假设一个解除引用的指针永远不会nullptr,如果它不是,那么任何后果都是程序员的问题.

由于编译器的复杂性令人震惊,其中一些后果可能会出乎意料.

当然,"任何事情都可能发生"并不是真的.您的计算机既没有必要的物理能力,也没有必要的合法权限来实例化猫的黑洞.但是由于C++是一种抽象,我们使用抽象来教人们不要编写具有未定义行为的程序似乎是恰当的.如果你严格编程,如果你的程序有不确定的行为,假设"任何事情都可能发生",那么你不会对所说的相当意外的后果感到惊讶,你也不会试图以任何方式"控制"结果.


sup*_*cat 6

从 C 和 C++ 标准的角度来看,某些情况调用“未定义行为”的事实无非是该标准没有对实现在该情况下必须做什么才能符合标准没有施加任何要求。它并不意味着对旨在用于任何特定平台上的目的的实现是否应该预期表现出可预测的行为进行任何特定的判断,也不意味着在这种情况下是否需要可预测的行为才能使实现适合在此类平台上的此类目的。

出于某种原因,一些编译器作者将“标准不需要 X”等同于“实现不需要做 X”,没有特别考虑他们的编译器的目的,也没有考虑什么为了实现这些目的,行为可能是必要的。导致未定义行为偏离“任何事情都可能发生”的原因是,编译器编写者将其解释为承认可能存在某些平台和应用程序领域的组合,在这些组合中,确保可预测行为的成本将超过收益,编译器编写者应该对何时出现这种情况做出判断,而是表明该标准的作者已经做出了判断,即在平台和应用程序领域的所有组合上,确保可预测行为的成本将超过收益,并且没有必要供编译器编写者进行判断,因为标准的作者已经这样做了。