C语言中有符号整数溢出是未定义行为还是实现定义行为?
结论:该赋值操作属于实现定义行为,不属于未定义行为
涉及的代码如下:
#include <limits.h> int main(){ int a = UINT_MAX; return 0; }
两种说法的核心差异是混淆了两类不同的有符号数值越界场景:
- 第一类是有符号整数执行算术运算时发生溢出,这类场景C标准明确规定属于未定义行为,也是部分资料描述的「有符号溢出是UB」的适用范围
- 第二类是无符号整数转换为有符号整数时,源值超出目标有符号类型的可表示范围,也就是当前代码对应的场景,C标准明确规定这类场景属于实现定义行为
针对无符号转有符号的越界场景,C标准的规则为:
若新类型是有符号类型且值无法在该类型中表示,结果是实现定义的,或者会触发实现定义的信号。
你观察到的GCC截断行为是主流编译器的通用实现:基于二进制补码规则做截断,32位环境下UINT_MAX的值为0xFFFFFFFF,转换为int后会固定得到-1,该行为是编译器明确定义、可复现的。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

