即使L后缀,C中的十六进制常量也是无符号的

tes*_*est 8 c comparison gcc compile-time-constant gcc-warning

我知道这是一个简单的问题,但我很困惑.我有一个相当典型的gcc警告,通常很容易修复:
warning: comparison between signed and unsigned integer expressions

每当我有一个带有最高有效位的十六进制常量时,如0x80000000L,编译器会将其解释为无符号.例如,使用-Wextra编译此代码将导致警告(gcc 4.4x,4.5x):

int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}
Run Code Online (Sandbox Code Playgroud)

我已经特别为常量加了后缀,为什么会发生这种情况呢?

Nem*_*emo 12

C中无符号十六进制常量的答案是相关的.带L后缀的十六进制常量将具有以下第一种可以保存其值的类型:

long
unsigned long
long long
unsigned long long
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅C99草案,[6.4.4.1]部分.

在您的平台上,long可能是32位,因此它不足以保持(正)常量0x80000000.所以你的常量有类型unsigned long,它是列表中的下一个类型,足以保存该值.

long64位的平台上,您的常量将具有类型long.

  • @cheshar:尝试我给出的参考(C99 草案,第 6.4.4.1 节);这是非常清楚的。它说“十进制常量的值以 10 为基数计算;八进制常量的值以 8 为基数计算;十六进制常量的值以 16 为基数计算”。因此“0x80000000”是以 16 为基数计算的,其值为 2^31。它的类型是列表中第一个可以表示该值的类型。32 位有符号“int”无法表示该值(因为它大于“INT_MAX”),因此这不是它的类型。 (2认同)