为了账号安全,请及时绑定邮箱和手机立即绑定

整数溢出和未定义的行为

整数溢出和未定义的行为

C
拉莫斯之舞 2019-12-04 15:05:34
由于可能,在实际加/减之前有很多关于整数溢出检测的问题undefined behavior。所以,我的问题是为什么会首先产生这种undefined behavior现象?我可以想到2个原因:1)在这种情况下会产生异常的处理器。当然,可以将其关闭,最可能的是编写良好的CRT。2)使用其他数字二进制表示形式的处理器(1的补码?以10为基数)。在这种情况下,未定义的行为将表现为不同的结果(但不会崩溃!)。好吧,我们可以忍受。那么,为什么有人要避免引起它呢?我想念什么吗?
查看完整描述

3 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

尽管大多数现代CPU使用2的补码,并且整数溢出会导致可预测的模数环绕,但这绝不是通用的-为了使该语言具有足够的通用性,使其可以在最广泛的体系结构上使用,最好将整数溢出指定为UB 。


查看完整回答
反对 回复 2019-12-04
?
慕森王

TA贡献1777条经验 获得超3个赞

尽管将签名溢出指定为未定义行为的历史原因可能是这些虚假的遗留表示(补码/符号幅度)和溢出中断,但使其保持未定义行为的现代原因是优化。正如J-16 SDiZ所暗示的那样,带符号的溢出是未定义的行为,这一事实使编译器可以优化某些条件,这些条件的代数真值(但不一定是表示层真值)已由先前的分支建立。它还可能允许编译器以某种方式代数简化某些表达式(尤其是涉及乘法或除法的表达式),如果子表达式包含溢出,则该表达式可能会给出与原始编写的求值顺序不同的结果,

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


查看完整回答
反对 回复 2019-12-04
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

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编译器并不是那么简单,它会进行大量的猜测和优化。


查看完整回答
反对 回复 2019-12-04
  • 3 回答
  • 0 关注
  • 733 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信