C 中的十六进制常量即使有 L 后缀也是无符号的
我知道这是一个简单的问题,但我很困惑。我有一个相当典型的 gcc 警告,通常很容易修复:警告:有符号和无符号整数表达式之间的比较
每当我有一个具有最高有效位的十六进制常量(例如 0x80000000L)时,编译器都会将其解释为无符号。例如,使用 -Wextra 编译此代码将导致警告 (gcc 4.4x, 4.5x):
int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}
我专门为常量添加了后缀 as long,那么为什么会发生这种情况呢?
I know this is a simple question but I'm confused. I have a fairly typical gcc warning that's usually easy to fix:warning: comparison between signed and unsigned integer expressions
Whenever I have a hexadecimal constant with the most significant bit, like 0x80000000L, the compiler interprets it as unsigned. For example compiling this code with -Wextra will cause the warning (gcc 4.4x, 4.5x):
int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}
I've specifically suffixed the constant as long, so why is this happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Unsigned hexadecimal Constant in C? 的答案是相关的。带有
L
后缀的十六进制常量将具有以下第一种可以保存其值的类型:请参阅 C99 草案,第 [ 6.4.4.1 ] 节,了解详细信息。
在您的平台上,
long
可能是 32 位,因此它不够大,无法容纳(正)常量0x80000000
。因此,您的常量具有unsigned long
类型,它是列表中的下一个类型,足以保存该值。在
long
为 64 位的平台上,常量的类型为long
。The answer to Unsigned hexadecimal constant in C? is relevant. A hex constant with
L
suffix will have the first of the following types that can hold its value:See the C99 draft, section [ 6.4.4.1 ], for details.
On your platform,
long
is probably 32 bits, so it is not large enough to hold the (positive) constant0x80000000
. So your constant has typeunsigned long
, which is the next type on the list and is sufficient to hold the value.On a platform where
long
was 64 bits, your constant would have typelong
.因为您的编译器使用 32 位
long
(大概也使用 32 位int
),并且0x80000000
不适合 32 位有符号整数,因此编译器将其解释为无符号整数。如何解决这个问题取决于您想要做什么。Because your compiler uses 32-bit
long
s (and presumably 32-bitint
s as well) and0x80000000
wont fit in a 32-bit signed integer, so the compiler interprets it as unsigned. How to work around this depends on what you're trying to do.那么它是一个无符号长整型。我猜测编译器决定最有可能需要无符号的十六进制文字。尝试转换它
(unsigned long)0x80000000L
It's an unsigned long then. I'm guessing the compiler decides that a hex literal like that is most likely desired to be unsigned. Try casting it
(unsigned long)0x80000000L
C/C++ 中的十六进制常量始终是无符号的。但是您可以使用显式类型转换来抑制警告。
Hex constants in C/C++ are always unsigned. But you may use explicit typecast to suppress warning.
根据 c 标准,十六进制常量是无符号的。
According to the c standard hex constants are unsigned.