有符号整数提升为无符号长整型

Signed integer promote to unsigned long

在 x86-64 linux 环境中,为什么 C 将有符号整数 -1 提升为无符号长整数 0xffffffffffffffff,而不是 0xffffffff?

#include <stdio.h>

int main() {
  unsigned long ul = (int)-1;
  printf("%lx\n", ul);
}

C11§6.3.1.3 Signed and unsigned integers ¶1,2:

When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60)

60) The rules describe arithmetic on the mathematical value, not the value of a given type of expression.

因此,-1 通过添加 ULONG_MAX + 1 进行转换,得到 ULONG_MAX,如您所见。您的系统必须为 unsigned long 类型使用 64 位。