Skip to content

Undefined Behavior ​

UB, 未定义的行为 —— 说明行为分为「定义」的和「未定义」的两种. (一如既往的废话)

未定义行为最神奇的一点在于我们写出来之后, 程序可能崩溃, 可能输出出乎意料的东西, 也可能因为编译器优化出现什么反直觉的东西.

定义 ​

先看什么是定义的行为, 首先标准实际上定义了一个”抽象机器“, 即 The Abstract Machine —— 也就是我们每一步操作应该有什么语义, 一个对象什么时候存在, 一次表达式如何求值, 一次函数调用产生什么效果, 一次内存访问在什么条件下是合法的……诸如此类. 也就是说对于一个合法程序, 那么它的行为就会在抽象机器中有一个具体体现, 不会出现“意料之外”的东西.

不过这只是语言层面上的东西, 对于编译器, 不会去规定它到底生成什么机器码, 只要编译器编译出来的机器码行为和这个抽象机器的行为一致即可 (as-if rule).

未定义 ​

那么“未定义行为”就非常好理解了 —— 标准中没有定义这样的行为, 在标准定义之外的所有操作, 就是未定义行为.

比如什么对 nullptr 解引用 —— 对于合法的指针解引用, C++ 标准规定了它的语义; 但是 nullptr 并没有指向一个可以被访问的对象, 因此这次操作违反了解引用所要求的条件. 于是从此, 程序进入 Undefined Behavior. 这个操作在规定标准定义的行为之外, 所以我们无法预测它到底会发生什么事情, 或崩溃, 或得到一个看似正常的结果, 或输出什么乱七八糟的.

Released under the MIT License.