2013-03-30 93 views
5

我有下面這個簡單的程序,我正在使用它來刷新我對GDB的記憶(我多年沒有碰過它)。GCC變化小於或等於

#include <stdio.h> 

int main() 
{ 
    int i; 

    for (i = 0; i < 10; i++) 
    { 
    printf("Hello World\n"); 
    } 

    return 0; 
} 

我編譯這個與gcc -g for-test.c -o for-test。根據手冊頁,我不期望使用任何優化,因爲我沒有指定任何優化。

當我這個裝入GDB和運行disassemble main,該i < 10比較產生如下:

cmp DWORD PTR [rbp-0x4],0x9 
jle 0x4004fe <main+10> 

這似乎已有效改變了i < 10一個比較i <= 9。鑑於這些是整數比較,不應該有差異,但我想知道GCC是否有任何理由輸出這個程序集,而不是比較10和跳躍,如果小於(JL)?

編輯:這是在一臺裝有64位處理器的機器上運行Ubuntu的GCC 4.6.3和GDB 7.4-2012.04。

+0

兩種方式100%相同(每個CPU上的行爲相同,代碼大小相同,速度相同)。我不知道GCC的內部結構,所以我猜不出它爲什麼這樣做。更有趣的是,我認爲你沒有啓用優化(否則它會使用寄存器而不是'i'的局部變量)。 – Brendan

+2

也許這就是它如何規範化比較.. – harold

+0

如果有兩個不一樣的機會,它不會沒有優化。例如'如果(a + 1> 1)'通過優化被簡化爲'if(a> 0)',但它可能是不安全的,所以不會這樣做。 – teppic

回答

5

執行速度不應該有差異。我認爲海灣合作委員會通常會發布這樣的比較,並在生成的程序集中保持一致。

+0

這似乎確實如此。有趣的是,我在clang中嘗試了相同的代碼,結果相反 - 如果「小於」則將「繼續循環」轉換爲「如果大於或等於'則打破循環」。我不確定爲什麼這兩個編譯器選擇了不同的路線,或者如果一個本質上比另一個更有效。 – pwaring

0

這不是有效的優化,只是另一種寫法相同。使用-O標誌進行編譯會生成更復雜的優化。

2

只要可觀察行爲相同,就允許編譯器執行優化。這就是所謂的As-If rule。由於這兩種情況的可觀察行爲是相同的,因此編譯器可以在兩者中的任何一箇中生成彙編代碼。即使您沒有啓用任何優化,情況也是如此。

+0

+1。它甚至可以展開循環(它實際上是用'-O3'做到的)。而且,甚至可以打印出一個單一的字符串,它是原件的10份。 –

+0

雖然這並不是一個優化,除非與9進行比較,如果小於或等於10,則跳躍比(或者更高的內存效率或其他度量)跳躍小於10,跳躍小於。 – pwaring