2013-10-15 93 views
1

我在Linux上使用GCC編譯器。
我想使用64位編譯器並使用-m32選項(32位兼容性)構建一些我的文件。我發現奇怪的(對我來說)編譯器的行爲。
我的代碼很簡單:GCC四倍大小32和64位

int main() { 
    int test =(((0) & 0x00000000) << (32)); 
    return 0; 
} 

而且此代碼我收到與-m32編譯器警告的326464

warning: left shift count >= width of type [enabled by default] 

當我試圖從assebmly code編譯它不過:

.quad (((0) & (0x00000000)) << (32)) 

我只收到01的警告編譯器:

Warning: shift count out of range (32 is not between 0 and 31) 

爲什麼是相同的代碼不同於c編譯和asm文件對於不同的編譯器(32和64位)警告?

編輯:

我在哪裏可以找到.quad定義,我指的是代碼?

+2

嘛,一個是從C編譯器,並從彙編另一方面,似乎沒有任何意義,使錯誤是完全一樣的,只要它們含有相同的信息。順便說一句。爲什麼這被標記爲C++? – PlasmaHH

+0

@PlasmaHH呃,對不起,我不想將'C++'添加到標籤... – Arseniy

回答

4

在64位模式下,gcc使用LP64約定。這意味着long和指針是64位寬,但int仍然只有32位寬。在表達

int test =(((0) & 0x00000000) << (32)); 

常量都假定爲ints,因爲int是大到足以容納所有這些,和int s爲永遠只有32位。由於該行爲通常取決於底層架構的移位指令,所以該類型的寬度> = =的結果是C中的UB。

通過強制其中一個數字爲64位來抑制警告。

long test =(((0) & 0x00000000L) << (32)); // Still gives a warning with -m32 

long long test =(((0) & 0x00000000LL) << (32)); // No warning, long long is always 64 bit 
+0

感謝您的完整解答。但爲什麼當我編譯asm代碼的結果(警告)不同? – Arseniy

+0

而且我該如何將'LL'添加到宏定義或'asm'文件中? – Arseniy

2

在C中,移位的左操作數的類型是int,在所討論的兩個平臺上都是32位,所以在C語言方面移位總是未定義的行爲。

我想你的彙編程序的操作數分別是32或64位。

+2

事實上,他正在使用'.quad',因此即使在32位模式下也能使它成爲64位。如果彙編程序正在產生警告,那是一個錯誤或一個限制。 – Jester