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

时间:2011-07-18 05:23:21

标签: c gcc comparison gcc-warning compile-time-constant

我知道这是一个简单的问题,但我很困惑。我有一个相当典型的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");
}

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

5 个答案:

答案 0 :(得分:12)

Unsigned hexadecimal constant in C?的答案是相关的。带有L后缀的十六进制常量将具有以下第一种可以保存其值的类型:

long
unsigned long
long long
unsigned long long

有关详细信息,请参阅C99 draft部分[6.4.4.1]。

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

long为64位的平台上,您的常量将为long类型。

答案 1 :(得分:1)

因为你的编译器使用32位long(也可能是32位int)并且0x80000000不适合32位有符号整数,所以编译器将其解释为未签名。如何解决这个问题取决于你想要做什么。

答案 2 :(得分:0)

根据c标准,十六进制常量是无符号的。

答案 3 :(得分:0)

那是一个无条件的长期。我猜测编译器决定像这样的十六进制文字最有可能是无符号的。尝试将其(unsigned long)0x80000000L

答案 4 :(得分:0)

C / C ++中的十六进制常量始终是无符号的。但是你可以使用显式类型转换来抑制警告。