我正在使用C中的整数,试图更多地探讨溢出何时以及如何发生。
我注意到当我添加两个正数时,其总和溢出,我总是得到一个负数。
另一方面,如果我添加两个负数,其总和溢出,我总是得到一个正数(包括0)。
我做了一些实验,但我想知道这是否适用于每一个案例。
整数溢出是C中未定义的行为。
C表示涉及整数溢出的表达式,如果在通常的算术转换之后的结果是带符号的类型,并且不能在结果的类型中表示。 赋值和强制转换表达式是一个例外,因为它们由整数转换来控制。
无符号类型的表达式不能溢出,它们换行,例如, 0U - 1
是UINT_MAX
。
例子:
INT_MAX + 1 // integer overflow UINT_MAX + 1 // no overflow, the resulting type is unsigned (unsigned char) INT_MAX // no overflow, integer conversion occurs
永远不要让任何整数表达式过度,现代编译器(如gcc
)利用整数溢出是未定义的行为来执行各种类型的优化。
例如:
a - 10 < 20
当a
在提升后为int
类型时,表达式在gcc
减少(启用优化时)到:
a < 30
当a
在INT_MIN + 10 - 1
到INT_MIN
范围内时,它利用表达式是未定义的行为。
当a
是unsigned int
时,无法完成此优化,因为如果a
为0
,则a - 10
必须被评估为UINT_MAX - 9
(没有未定义的行为)。 当a
为0
到9
时,优化a - 10 < 20
到a < 30
将导致与所需结果不同的结果。
有符号整数的溢出是C中未定义的行为,因此无法保证。
也就是说,环绕或算术模2 N ,其中N
是类型中的位数,是一种常见的行为。 对于那种行为,实际上如果一个和溢出,结果与操作数的符号相反。
forms上,有符号算术对溢出的行为是不确定的; 任何事情都可能发生,而且是’正确的’。 这与无符号算术形成对比,后者完全定义了溢出。
在实践中,许多较旧的编译器使用了在您描述时溢出的带符号算法。 然而,现代海湾合作委员会正在改变其运作方式,你依赖这种行为是非常不明智的。 当编译代码的环境中的任何内容发生变化时,它可能随时发生变化 – 编译器,平台……
以上就是c/c++开发分享C整数溢出相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522123.html