c - 警告 : this decimal constant is unsigned only in ISO C90

标签 c compiler-construction long-integer iso c89

一段代码:

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 版本中,无后缀十进制整数常量的类型是 intlong intunsigned long int 中的第一个,其中它的值(value)是可以体现的。 (C90 没有long longunsigned long long 类型)。

在1999和2011版本中,其类型为intlong intlong 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 位 int2147483647int 类型,表达式的结果产生预期的 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/

相关文章:

php - 如何整合PHP和C程序?

c - 选择外部调用的特定寄存器

visual-studio-2010 - 哪些编译器支持 CUDA

c - rpc remote proceduer 编译错误

c - C中指向多维​​数组的指针?

testing - 测量 Javacc 解析器性能

C# - 值类型等于方法 - 为什么编译器使用反射?

java - 将2个long转换为对应的byte[],并在中间加上分隔符

c - struct itimerspec 中的浮点值

java - 如何保存方法的输出以便在不同的方法中使用它?