Win7(64位)+Code::Blocks17.12环境下。下面两段代码的差别是什么?
void main()
{
int a;
a=2147483647+1;
}
void main()
{
int a;
a=2147483648;
}
为什么第一段编译时提示溢出错误,第二段却编译正确。
2147483647和1都默认是int类型,所以编译器在计算的时候,默认结果也认为是int类型,编译器在将2147483648这个计算结果赋值给int变量时,会进行安全性检查,这个结果超出最大整数范围,所以编译器会报错。
但是,int a = 2147483648这么写的时候,编译器只把2147483648作为一个数字常量,并用二进制存储,但是,因为编译器无法判断这个数的正负性,就像0XFF这个数,你可以认为他是正数,也可认为它是负数,因为没有明确的符号来说明这个数的正负性,同理2147483648这个数,编译器也无法判断用户的目的是想输入正数还是负数,负数的话是不越界的,所以这么写的时候,编译器不会报错。
c语言中,int最大值是2147483647,在+1,所以这个就溢出了,所以报错
而后面那个赋值语句: a=2147483648;如果直接输出变量a不加格式化输出也是会出错,但是加上格式化输出“%d”,得出的结果却不是2147483648,而是饮食转化成了-2147483648;这是因为int类型最小值就是:-2147483648
int能表示的最大值是2147483647
第一个会造成计算移出,无法存储在一个int类型中
第二个他自己截断了,你可以尝试输出a,应该是-1
就是直接赋值会阶段,但是计算溢出会报错
From https://en.cppreference.com/w/cpp/language/operator_arithmetic#Overflows
Overflows
Unsigned integer arithmetic is always performed modulo 2^n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives 0, and subtracting one from 0 gives UINT_MAX.
When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined, — the possible manifestations of such an operation include:
- it wraps around according to the rules of the representation (typically 2's complement),
- it traps — on some platforms or due to compiler options (e.g. -ftrapv in GCC and Clang),
- it saturates to minimal or maximal value (on many DSPs),
- it is completely optimized out by the compiler.
From https://en.cppreference.com/w/c/language/conversion#Integer_conversions
Integer conversions
A value of any integer type can be implicitly converted to any other integer type. Except where covered by promotions and boolean conversions above, the rules are:
if the target type can represent the value, the value is unchanged
otherwise, if the target type is unsigned, the value 2^b, where b is the number of bits in the target type, is repeatedly subtracted or added to the source value until the result fits in the target type. In other words, unsigned integers implement modulo arithmetic.
otherwise, if the target type is signed, the behavior is implementation-defined (which may include raising a signal)