[英]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 long
或unsigned 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
$
一個int
的大小確實取決於編譯器/系統。 但是,這並不是什么新鮮事物,所以很奇怪的是,對於較早的版本,該代碼未達到您的期望,而對於較新的版本,它還會發出警告。
為了解決這個問題,請考慮在常量上使用明確的位大小,例如117901309ll
。 這幾個合適的哪個取決於您的用例,在任何情況下,我都會考慮使用一個無符號值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.