简体   繁体   English

我更新的gcc编译器警告

[英]Warning with my updated gcc compiler

Getting this warning with my new gcc compiler 6.X version. 我的新gcc编译器6.X版本收到此警告。

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

I have defined a macro with #define CLON 0x070707FD in my code which converts to decimal value shown above in the warning. 我在代码中定义了#define CLON 0x070707FD宏,该宏转换为警告中上面显示的十进制值。

It seems like int is taking 4 bytes as I am running on a 64-bit machine. 当我在64位计算机上运行时,好像int正在占用4个字节。 But I'm not sure how it went fine on earlier gcc version, say 4.X version. 但是我不确定在早期的gcc版本(例如4.X版本)上如何运行。 Can any one please help me understanding this? 谁能帮我理解这一点吗?

The new compiler is warning you about undefined behaviour which the old compiler did not warn you about. 新的编译器警告您有关未定义行为的信息,而旧编译器并未警告您。 Be grateful, and finish your upgrade by moving to GCC 7.2.0, which is the latest GA version of GCC. 不胜感激,并通过升级到GCC的最新GA版本GCC 7.2.0完成升级。

The C11 standard §6.5.7 Bitwise shift operators says: C11标准§6.5.7按位移位运算符说:

The result of E1 << E2 is E1 left-shifted E2 bit positions; E1 << E2的结果是E1左移E2位位置; vacated bits are filled with zeros. 空位用零填充。 If E1 has an unsigned type, the value of the result is E1 × 2 E2 , reduced modulo one more than the maximum value representable in the result type. 如果E1具有无符号类型,则结果的值为E1×2 E2 ,比结果类型中可表示的最大值模减少一个。 If E1 has a signed type and nonnegative value, and E1 × 2 E2 is representable in the result type, then that is the resulting value; 如果E1具有带符号的类型和非负值,并且E1×2 E2在结果类型中可表示,则这是结果值; otherwise, the behavior is undefined. 否则,行为是不确定的。

Since your result requires 52-bits, it is not representable in a 32-bit signed integer, and the compiler is correctly warning you that you're invoking undefined behaviour — which is something you should avoid doing. 由于您的结果需要52位,因此它不能用32位有符号整数表示,并且编译器正确地警告您正在调用未定义的行为 -您应避免这样做。

There are many ways of fixing the problem, but perhaps this is the simplest fix — change the type of CLON to unsigned with the U suffix (or you could use UL or even ULL if you really wanted unsigned long or unsigned long long results): 有很多解决问题的方法,但是也许这是最简单的解决方法-将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;
}

When that code is in a file sw73.c , you can compile it like so: 当该代码位于文件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
$

You need to specify explicit size to be used. 您需要指定要使用的显式大小。 You need to define the macro as 您需要将宏定义为

#define CLON 0x070707FDU

Or 要么

#define CLON 0x070707FDL

You may refer to ULL suffix on a numeric literal . 您可以在数字文字上引用ULL后缀

The size of an int is indeed compiler/system-dependent. 一个int的大小确实取决于编译器/系统。 However, that is nothing new, so odds are that with earlier versions the code didn't do what you expect already, only that with newer versions it also issues a warning. 但是,这并不是什么新鲜事物,所以很奇怪的是,对于较早的版本,该代码未达到您的期望,而对于较新的版本,它还会发出警告。

In order to fix that, consider using explicit bit sizes on the constant, like eg 117901309ll . 为了解决这个问题,请考虑在常量上使用明确的位大小,例如117901309ll Which of the several ones is appropriate here depends on your use case, in any case I'd consider using an unsigned value, too. 这几个合适的哪个取决于您的用例,在任何情况下,我都会考虑使用一个无符号值。

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

相关问题 Gcc 编译器抑制比较警告 - Gcc compiler suppress comparison warning 使用GCC编译器的UDP recvfrom警告 - UDP recvfrom warning with gcc compiler 我的 gcc 编译器警告我函数的隐式声明,即使声明在代码中明确给出 - My gcc compiler giving me warning for implicit declaration of function even though the declaration is clearly given in the code 用于指针算术警告的 c gcc 编译器选项 - c gcc compiler options for pointer arithmetic warning C-gcc:没有使用不同的函数声明/实现的编译器警告 - C - gcc: no compiler warning with different function-declaration/implementation 是否有任何 gcc 编译器警告可以捕获此 memory 错误? - Is there any gcc compiler warning which could have caught this memory bug? gcc 编译器忽略调试构建的未初始化变量警告 - gcc compiler ignores uninitialized variable warning for debug build gcc编译器报告警告,但a.out可以正常运行 - gcc compiler report warning but a.out works smoothly otherwise 我的gcc编译器给我一个错误,显示为(函数)的冲突类型 - My gcc compiler gives me an, error that shows as Conflicting types for (function) gcc 编译器是否尊重我的代码中编写的表达式形式? - Does the gcc compiler respect the form of expressions as written in my code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM