簡體   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