小编Jos*_*hua的帖子

如果 C 编译器无法证明缺少 UB,为什么要禁止优化?

如果 C 程序有未定义的行为,任何事情都可能发生。因此编译器可能会假设任何给定的程序不包含 UB。因此,假设我们的程序包含以下内容:

\n
x += 5;\n/* Do something else without x in the meantime. */ \nx += 7;\n
Run Code Online (Sandbox Code Playgroud)\n

当然,这可以优化为

\n
/* Do something without x. */\nx += 12;\n
Run Code Online (Sandbox Code Playgroud)\n

或类似的其他方式。

\n

如果 x 具有类型,unsigned int则上述程序中不可能出现 UB。另一方面,如果 x 有类型signed int,则有可能溢出,从而产生 UB。由于编译器可能会假设我们的程序不包含UB,因此我们可以进行与上面相同的优化。事实上,在这种情况下,编译器甚至可以假设x - 12 <= MAX_INT.

\n

然而,这似乎与 Jens Gustedt 著名的“Modern C”(第 42 页)相矛盾:

\n
\n

但这样的优化也可以被禁止,因为编译器无法证明某个操作不会强制程序终止。在我们的示例中,很大程度上取决于 x 的类型。如果 x 的当前值可能接近类型的上限,则看似无辜的操作 x += 7 可能会产生溢出。此类溢出根据类型的不同而有不同的处理方式。正如我们所看到的,无符号类型的溢出不是问题,并且压缩运算的结果将始终与两个单独的结果一致。对于其他类型,例如有符号整数类型(signed)和浮点类型(double),溢出可能会引发异常并终止程序。在这种情况下,无法执行优化。

\n
\n

(强调我的)。如果编译器可以(并且确实)假设我们的程序没有 UB,为什么不能执行此优化?

\n …

c optimization integer-overflow compiler-optimization undefined-behavior

24
推荐指数
1
解决办法
3838
查看次数