use*_*514 20 c compiler-construction iso c89 long-integer
一段代码:
long rangeVar = 0;
rangeVar = atol(p_value);
if (rangeVar >= -2147483648 && rangeVar <= 2147483647)
Run Code Online (Sandbox Code Playgroud)
在编译时,我得到:
警告:此十进制常量仅在ISO C90中无符号
提前致谢
Kei*_*son 15
十进制整数常量类型的规则在ISO C标准的1990和1999版本之间改变.
在1990年版,一个无后缀十进制整数常量的类型是第一的int,long int或unsigned long int在其值可以被表示.(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.您可以添加Ufor unsigned int,Lfor long,ULfor unsigned long等等.
重要的是要记住,重要的-2147483648是不是一个整型常量; 相反2147483648,它本身是一个整型常量,-2147483648是一个将一元减运算符应用于该常量的表达式.根据C90规则,如果常量是类型unsigned long,那么这是一个无符号一元减号,它在无符号算术的规则下产生该值2147483648.根据C99或C11规则,2147483648可能是类型(签名)long long,并且否定它的收益-2147483648,也是类型long long.
您有时会看到(-2147483647 - 1)用于避免此问题的代码; 给定的32位int,2147483647是类型int和表达的结果产生的预期int值,而不溢出.
当然,如果您的编译器具有不同的整数类型大小,这可能会变得更加复杂.
Mr *_*ter 10
是的,这是编译器无法很好地处理的一件事.问题是在编译期间,这是否定的数字2147483648,并且2147483648超出整数的范围.即使-2147483648不会!
无论如何,要消除警告,您可以通过写入将常量转换为64位数-2147483648LL.
但这有点过分,所以首选的方法是使用INT_MIN常数.但是你需要包括<limits.h>.