我不应该被警告 -INT_MIN 的未定义行为吗?



考虑以下C程序:

#include <limits.h>
int main() {
int x = INT_MIN;
int y = -x;
return y;
}

这个程序有未定义的行为,因为INT_MIN的否定是不可表示的;或者,成为一名语言律师——因为C标准是这么说的。

现在,编译器知道,或者可以知道,就是这种情况。然而,GCC和clang都没有对此发出警告,即使是-W -Wall -Wextra(GodBolt);只有对未定义行为进行消毒才能在运行时捕获它。

为什么会这样?通常,试图证明UB在编译时发生的成本是否太高,因此编译器不需要费心?

在使用某些实现或配置时,这样的构造是安全的。当使用启用了优化但没有-fwrapv的clang或gcc时,这样的结构可能会导致其他地方的代码以不受普通因果律约束的方式被无意义地处理。

用C标准的话说,代码是不可移植的或错误的。从已发布的基本原理来看,很明显,标准想要这个短语包括不可移植的,但是当用于执行适合低级编程的实现的低级任务时,正确的结构。然而,标准给了编译器编写者自由,他们的客户不会故意在低级编程中使用这些结构,可以将它们视为"错误的"。在这种情况下,这比假设他们是故意的,但不能携带更有用。那些希望把他们的编译器卖给将要使用它们的程序员的人,会比委员会更了解他们的客户会故意使用哪些结构,因此没有必要让标准本身做出这样的区分。

然而,一些不受这种市场压力影响的编译器在不同的理念下运行,其中短语"不可移植或错误";意思是"不可移植",因此是错误的。因此,即使在整数溢出在机器码级别上永远不会有任何副作用的平台上,这些编译器有时也可能在确定整数溢出不可避免的情况下不自觉地表现出来,即使程序行为的任何方面都不会与计算结果有任何因果关系。

相关内容

  • 没有找到相关文章

最新更新