繁体   English   中英

C编译器无法识别unsigned long

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM