用我更新的gcc编译器警告

时间:2018-01-09 06:49:42

标签: c gcc

使用我的新gcc编译器6.X版本获取此警告。

warning: result of '117901309 << 24' requires 52 bits to represent,
but 'int' only has 32 bits [-Wshift-overflow=]

我在代码中定义了一个带#define CLON 0x070707FD的宏,该宏转换为警告中显示的十进制值。

当我在64位计算机上运行时,似乎int占用了4个字节。但是我不确定它在早期的gcc版本上是如何运行的,比如4.X版本。任何人都可以帮我理解这个吗?

3 个答案:

答案 0 :(得分:3)

新编译器警告您有关未定义的行为,旧编译器没有警告您。不胜感激,请完成升级到GCC 7.2.0,这是GCC的最新GA版本。

C11标准§6.5.7 Bitwise shift operators说:

  

E1 << E2的结果是E1左移E2位位置;腾出的位充满了   零。如果E1具有无符号类型,则结果的值为E1×2 E2 ,减少模数   比结果类型中可表示的最大值多一个。如果E1已签名   类型和非负值,E1×2 E2 在结果类型中可表示,那么   结果价值;否则,行为未定义。

由于您的结果需要52位,因此无法在32位有符号整数中表示,并且编译器正确地警告您正在调用未定义的行为 - 这是您应该做的事情避免这样做。

解决问题的方法有很多种,但也许这是最简单的解决方法 - 使用CLON后缀将unsigned的类型更改为U(或者您可以使用{{ 1}}甚至UL如果您真的想要ULLunsigned long结果):

unsigned long long

当该代码在文件#define CLON 0x070707FD #define ULON 0x070707FDU int shift_CLON(void); unsigned shift_ULON(void); int shift_CLON(void) { return CLON << 24; } unsigned shift_ULON(void) { return ULON << 24; } 中时,您可以这样编译它:

sw73.c

答案 1 :(得分:1)

您需要指定要使用的显式大小。您需要将宏定义为

#define CLON 0x070707FDU

或者

#define CLON 0x070707FDL

您可以参考ULL suffix on a numeric literal

答案 2 :(得分:0)

int的大小确实是编译器/系统依赖的。然而,这并不是什么新鲜事,因此在早期版本中,代码并没有达到您的预期,只有在较新版本的情况下,它才会发出警告。

为了解决这个问题,请考虑在常量上使用显式位大小,例如117901309ll。这里适当的几个取决于您的使用案例,无论如何我也考虑使用无符号值。

相关问题