整数溢出和未定义的行为

由于可能存在undefined behavior因此在实际加/减之前检测整数溢出有很多问题。 所以,我的问题是

为什么它会首先产生这种undefined behavior

我可以想到两个原因:

1)在这种情况下生成exception的处理器。 当然,它可以切换,很可能是一个写得很好的CRT会做到这一点。

2)使用数字的其他二进制表示的处理器(1的补码?基数10?)。 在这种情况下,未定义的行为将表现为不同的结果(但不会崩溃!)。 好吧,我们可以忍受。

那么,为什么有人会避免造成它呢? 我错过了什么吗?

虽然大多数现代CPU使用2的补码,并且整数溢出导致可预测的模数环绕,但这绝不是通用的 – 为了保持语言足够通用以便可以在最广泛的体系结构上使用,最好指定整数溢出是UB 。

虽然签名溢出的历史原因被指定为未定义的行为可能是这些虚假的遗留表示(补码/符号幅度)和溢出中断,但它保持未定义行为的现代原因是优化。 正如J-16 SDiZ所暗示的那样,签名溢出是未定义的行为允许编译器优化一些条件,其代数事实(但不一定是表示级别的事实)已经由前一个分支建立。 它还可以允许编译器以代数方式简化某些表达式(特别是涉及乘法或除法的表达式),如果子表达式包含溢出,则可以提供与最初编写的求值顺序不同的结果,因为允许编译器假定溢出你给它的操作数不会发生。

为了允许优化,另一个未定义行为的巨大示例是别名规则。

规范中undefined behavior位涉及一些编译器优化。 例如:

 if (a > 0 && b > 0) { if ( a + b <= 0 ) { // this branch may be optimized out by compiler } else { // this branch will always run } } 

现代C编译器并不那么简单,它做了大量的猜测和优化。

我认为你的假设1)如果我的记忆是正确的,至少在一个重要的历史架构CDC上可以关闭任何给定的处理器。