如果 C 程序有未定义的行为,任何事情都可能发生。因此编译器可能会假设任何给定的程序不包含 UB。因此,假设我们的程序包含以下内容:
\nx += 5;\n/* Do something else without x in the meantime. */ \nx += 7;\nRun Code Online (Sandbox Code Playgroud)\n当然,这可以优化为
\n/* Do something without x. */\nx += 12;\nRun Code Online (Sandbox Code Playgroud)\n或类似的其他方式。
\n如果 x 具有类型,unsigned int则上述程序中不可能出现 UB。另一方面,如果 x 有类型signed int,则有可能溢出,从而产生 UB。由于编译器可能会假设我们的程序不包含UB,因此我们可以进行与上面相同的优化。事实上,在这种情况下,编译器甚至可以假设x - 12 <= MAX_INT.
然而,这似乎与 Jens Gustedt 著名的“Modern C”(第 42 页)相矛盾:
\n\n\n但这样的优化也可以被禁止,因为编译器无法证明某个操作不会强制程序终止。在我们的示例中,很大程度上取决于 x 的类型。如果 x 的当前值可能接近类型的上限,则看似无辜的操作 x += 7 可能会产生溢出。此类溢出根据类型的不同而有不同的处理方式。正如我们所看到的,无符号类型的溢出不是问题,并且压缩运算的结果将始终与两个单独的结果一致。对于其他类型,例如有符号整数类型(signed)和浮点类型(double),溢出可能会引发异常并终止程序。在这种情况下,无法执行优化。
\n
(强调我的)。如果编译器可以(并且确实)假设我们的程序没有 UB,为什么不能执行此优化?
\n …c optimization integer-overflow compiler-optimization undefined-behavior