我在 C 规范中读到了一些无符号变量(特别是无符号短int
)执行一些所谓的环绕关于整数溢出,尽管我在有符号变量上找不到任何东西,除了我留下的未定义的行为.
我的教授告诉我,他们的价值观也被包裹起来(也许他只是指海湾合作委员会)。我认为这些位只是被截断了,而我留下的位给了我一些奇怪的价值!
环绕是什么以及它与仅截断位有何不同。
有符号整型变量在 C 语言中没有环绕行为。算术计算期间有符号整数溢出会产生未定义的行为。请注意,您提到的 GCC 编译器以实现而闻名严格的溢出语义在优化中,这意味着它利用了此类未定义行为情况所提供的自由度:GCC 编译器假定有符号整数值永远不会回绕。这意味着 GCC 实际上恰好是您使用的编译器之一cannot依赖于有符号整数类型的环绕行为。
例如,GCC 编译器可以假设对于变量int i
以下条件
if (i > 0 && i + 1 > 0)
相当于仅仅
if (i > 0)
这正是严格的溢出语义 means.
无符号整数类型实现模算术。模数相等2^N
where N
是类型的值表示中的位数。因此,无符号整数类型确实会在溢出时出现回绕。
然而,C 语言从不执行小于以下域的算术计算:int
/unsigned int
. Type unsigned short int
您在问题中提到的通常会被提升为类型int
在任何计算开始之前的表达式中(假设范围unsigned short
符合范围int
)。这意味着 1) 的计算unsigned short int
将在域中执行int
,溢出发生时int
溢出,2) 此类计算期间的溢出将导致未定义的行为,而不是环绕行为。
例如,这段代码会产生一个环绕
unsigned i = USHRT_MAX;
i *= INT_MAX; /* <- unsigned arithmetic, overflows, wraps around */
而这段代码
unsigned short i = USHRT_MAX;
i *= INT_MAX; /* <- signed arithmetic, overflows, produces undefined behavior */
导致未定义的行为。
If no int
发生溢出并且结果被转换回unsigned short int
类型,再次按模减少2^N
,这看起来就像该值已回绕一样。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)