[英]C compiler not recognizing unsigned long
在我的计算机上, long
取最大值9223372036854775807
。 但是,当我厌倦了带有较大值的unsigned long
,编译器会抛出一个警告,说明当我已经定义它时,它需要被解释为unsigned long
。 为什么会这样?
//assigning maximum value of a long integer. (No error)
long max_l = 9223372036854775807L;
//assigning an unsigned long integer.
unsigned long max_ul = 9223372036854775808L; //warning: integer literal is too large to be represented in a signed
//integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]
cc --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
这个整数常量:
9223372036854775808L
太大了,不能long
存放。
相反,使用:
9223372036854775808UL
这通过附加后缀UL
指定常量具有unsigned long
类型
或者只使用后缀U
:
unsigned long max_ul = 9223372036854775808U;
当整数常量具有后缀L
(或l
)时,编译器将按以下顺序确定其类型:第一种类型
signed long
signed long long
其值可以表示。 似乎signed long
类型signed long long
编译器建立的signed long long
类型具有相同的整数表示。 因此, signed long
类型和signed long long
类型都不能代表常量。 对于这些类型,常量太大了。 但是类型unsigned long
与编译器建立的unsigned long long
类型具有相同的内部表示,可以表示常量。
还要注意C中没有负整数常量。例如,你会写
int x = -1;
然后编译器将构造-1
拆分为两个标记:整数常量1
和一元运算符-
。
考虑以下示范程序
#include <stdio.h>
int main(void)
{
int a[] = { 0, 1, 2 };
int *p = a + 1;
printf( "p[-1] = %d\n", p[-1] );
printf( "-1[p] = %d\n", -1[p] );
return 0;
}
程序输出是
p[-1] = 0
-1[p] = -2
表达式-1[p]
与表达式(-1)[p]
。 它被处理为-(1[p] )
,相当于-p[1]
。
每个整数常量,如9223372036854775808
都有自己的类型。 编译器在程序中选择整数常量的类型有一些规则。 对于普通的十进制常量(没有任何U,L后缀),它是这样的:
int
。 long
。 long long
。 (详情请参阅C17 6.4.4.1中的表格)
显然,所有这些检查都因系统上的值2 ^ 63而失败,这是预期的,因为有符号的64位仅上升到2 ^ 63-1。
添加L
并没有解决任何问题,因为这只会告诉编译器执行上述检查但是以long
开头。
声明将整数常量存储为无符号的类型不能解决任何问题,因为赋值/初始化左侧的类型与整型常量的类型无关。 你可以写my_custom_type x = 9223372036854775808L;
而且你会得到同样的警告。
显而易见的解决方案是使用无符号后缀U
否则,如果由于某种原因需要> 63位值签名,你需要找到一些128位签名的“big int”库,这将更加痛苦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.