如何修复此编译器警告的原因?

时间:2010-09-07 22:01:06

标签: c 32bit-64bit

以下代码在32位系统上编译时会产生警告: 1087: warning: integer constant is too large for "long" type;我怎么能解决这个问题所以我没有得到那个警告,它在32位上正常工作?

有效的输入是:

unsigned char str[] = "\x00\x17\x7c\x3a\x67\x4e\xcb\x01";

并且mypow函数返回unsigned long long。

     unsigned long long high, low, nano;
     high = // line 1087
         (str[7]&0xff) * mypow(2,56) +
         (str[6]&0xff) * mypow(2,48) +
         (str[5]&0xff) * mypow(2,40) +
         (str[4]&0xff) * mypow(2, 32);
     low =
         (str[3]&0xff) * mypow(2,24) +
         (str[2]&0xff) * mypow(2,16) +
         (str[1]&0xff) * mypow(2,8) +
         (str[0]&0xff);
     nano = ((high + low)/10000000) - (unsigned long long)11644473600;
     return localtime((time_t*)&nano);

6 个答案:

答案 0 :(得分:6)

如果您在代码中使用的常量不适合32位,请在其末尾添加LL,以便编译器知道它应该是“long long”类型。例如,nano =行末尾的常量应为11644473600LL。当前代码将常量强制转换为long long,但常量本身是常规long,因为没有明确的LL后缀。

答案 1 :(得分:2)

它认为1000000是32位值。要明确它很长:

nano = ((high + low)/10000000L) - 11644473600L;

编辑:ULL将是正确的后缀。

答案 2 :(得分:2)

我相信你需要做11644473600ULL

答案 3 :(得分:2)

您问题的最可能正确答案是您必须在C89 / 90模式下使用C编译器(或者在C ++模式下?)。在C89 / 90和C ++中,最大的整数类型是long。在这些语言中没有long long这样的类型。然而,一些编译器支持long long作为非标准扩展。当您在代码中使用对于long类型而言太大的常量时,编译器必须拒绝您的代码或将常量提升为非标准long long类型。在后一种情况下,会发出警告,以通知您隐式引入代码的非标准类型。

虽然带有LLULL后缀的解决方案可能会阻止警告,但如果您真的想在代码中使用long long类型,我仍建议您编译你的代码是C99模式,这种类型是标准的。在C99模式下,无论后缀如何,警告都应自行消失。

答案 4 :(得分:1)

您应该使用stdint.h定义的整数类型来实现跨平台的可移植性。

例如,您应该尝试使用uint64_t而不是unsigned long long。这样你就可以准确地知道你获得了多少比特,并且它在所有平台上都是一样的。

答案 5 :(得分:0)

-std=c99命令行上使用gcc,警告将消失,因为C99对于这么大的整数常量有明确定义的行为。