长整数运算中的歧义?

看看下面这段代码:

#include  int main(void) { int a; a = 2147483647; printf("a + 1 = %d \t sizeof (a + 1) = %lu\n", a + 1, sizeof (a + 1)); printf("a + 1L = %ld \t sizeof (a + 1L) = %lu\n", a + 1L, sizeof (a + 1L)); a = -1; printf("a + 1 = %d \t sizeof (a + 1) = %lu\n", a + 1, sizeof (a + 1)); printf("a + 1L = %ld \t sizeof (a + 1) = %lu\n", a + 1L, sizeof (a + 1L)); //why a + 1L does not yield long integer ? return 0; } 

这导致以下输出:

 a + 1 = -2147483648 sizeof (a + 1) = 4 a + 1L = 2147483648 sizeof (a + 1L) = 8 a + 1 = 0 sizeof (a + 1) = 4 a + 1L = 0 sizeof (a + 1) = 8 

为什么最后一行中a + 1L产生0而不是长整数为4294967296?

为什么最后一行中的+ 1L不会产生长整数为4294967296?

因为将int -1转换为long int导致long int的值为-1,并且-1 + 1 = 0

如果目标类型是无符号的32位类型,则将-1转换为另一种类型只会导致4294967295 (通常, unsigned int就是这样,通常是uint32_t ,如果提供的话)。 但是,将值加1将换行为0。

因此要获得4294967296 ,你需要一个中间演员,

 (uint32_t)a + 1L 

这样-1首先转换为值为4294967295uint32_t ,然后转换为long

在第一种情况下:2147483647是32位有符号值,hex表示为0x7fffffff。 向它添加1会给出一个32位值,hex0x80000000,在32位有符号int中为-2147483648(由于溢出),如果被视为64位有符号int,则为2147483648。

在第二种情况下:-1是32位有符号值,hex表示为0xffffffff。 向它添加1将为您提供32位值,hex0x00000000,在signed int中为0。

当你以64位加1时,首先会发生符号扩展 ,所以你真的加了0xFFFFFFFFFFFFFFFF和0x0000000000000001,总和是0。

如果考虑符号扩展,则没有歧义。