繁体   English   中英

我更新的gcc编译器警告

[英]Warning with my updated gcc compiler

我的新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版本)上如何运行。 谁能帮我理解这一点吗?

新的编译器警告您有关未定义行为的信息,而旧编译器并未警告您。 不胜感激,并通过升级到GCC的最新GA版本GCC 7.2.0完成升级。

C11标准§6.5.7按位移位运算符说:

E1 << E2的结果是E1左移E2位位置; 空位用零填充。 如果E1具有无符号类型,则结果的值为E1×2 E2 ,比结果类型中可表示的最大值模减少一个。 如果E1具有带符号的类型和非负值,并且E1×2 E2在结果类型中可表示,则这是结果值; 否则,行为是不确定的。

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

有很多解决问题的方法,但是也许这是最简单的解决方法-将CLON的类型CLON为带有U后缀的unsigned (或者,如果您确实想要unsigned longunsigned long long结果,则可以使用UL甚至ULL ):

#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 ,您可以像这样编译它:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes -c sw73.c
sw73.c: In function ‘shift_CLON’:
sw73.c:9:17: error: result of ‘117901309 << 24’ requires 52 bits to represent, but ‘int’ only has 32 bits [-Werror=shift-overflow=]
     return CLON << 24;
                 ^~
cc1: all warnings being treated as errors
$

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

#define CLON 0x070707FDU

要么

#define CLON 0x070707FDL

您可以在数字文字上引用ULL后缀

一个int的大小确实取决于编译器/系统。 但是,这并不是什么新鲜事物,所以很奇怪的是,对于较早的版本,该代码未达到您的期望,而对于较新的版本,它还会发出警告。

为了解决这个问题,请考虑在常量上使用明确的位大小,例如117901309ll 这几个合适的哪个取决于您的用例,在任何情况下,我都会考虑使用一个无符号值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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