一段代码:
long rangeVar = 0;
rangeVar = atol(p_value);
if (rangeVar >= -2147483648 && rangeVar <= 2147483647)
在编译时我得到:
warning: this decimal constant is unsigned only in ISO C90
提前致谢
最佳答案
十进制整数常量类型的规则在 ISO C 标准的 1990 版和 1999 版之间发生了变化。
在 1990 版本中,无后缀十进制整数常量的类型是 int
、long int
或 unsigned long int
中的第一个,其中它的值(value)是可以体现的。 (C90 没有long long
或unsigned long long
类型)。
在1999和2011版本中,其类型为int
、long int
、long long int
之一;它从来不是任何无符号类型。
特定常量的类型(例如 2147483648
)将根据您使用的编译器的整数类型范围而有所不同。如果您的编译器的 long
类型恰好是 32 位,那么 2147483648
将是 unsigned long
类型(如果您的编译器使用 C90 规则)或类型long long
如果它使用 C11 规则(long long
保证至少为 64 位)。编译器会就此警告您。
您可以添加后缀来指定常量的类型——但是没有用于纯符号 int
的后缀。您可以为 unsigned int
添加 U
,为 long
添加 L
,为 unsigned 添加 UL
长等等。
请务必牢记 -2147483648
不是整数常量;相反,2147483648
本身是一个整数常量,而 -2147483648
是一个将一元减号运算符应用于该常量的表达式。在 C90 规则下,如果常量是 unsigned long
类型,则为 unsigned 一元减法,根据无符号算术规则,其产生值 2147483648
。在 C99 或 C11 规则下,2147483648
可能是类型(有符号)long long
,取反得到 -2147483648
,也是类型long long
.
您有时会看到使用 (-2147483647 - 1)
的代码来避免这个问题;给定一个 32 位 int
,2147483647
是 int
类型,表达式的结果产生预期的 int
没有溢出的值。
当然,如果您的编译器对整数类型有不同的大小,这可能会变得更加复杂。
更新:当我写这篇文章时,gcc 的默认方言是 -std=gnu89
。从那时起,它已更改为 -std=gnu11
(或未发布版本中的 -std=gnu17
)。我不确定这对警告有何影响。
关于c - 警告 : this decimal constant is unsigned only in ISO C90,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9941261/