2013-08-01 74 views
1

我有以下代碼段,編譯器優化,分割宏擴展

方案1

/* get count of elements in an array */ 
#define COUNT(x)   sizeof(x)/sizeof(x[0]) 

struct Data data[] = {/* some data goes here */}; 

int count = COUNT(data); 

方案2

#define TOTAL   32 
#define EACH    4 
int count = (TOTAL/EACH) 

我知道宏期間解析預處理和sizeof是一個編譯但是這個部門呢:它在編譯期間是否被優化了?

有什麼工具可以看到編譯器完成的優化嗎?

+0

該工具是您的編譯器 - 可能它有一個標誌,使其顯示預處理輸出,以及程序集生成 – stijn

+1

你可以看到彙編代碼來找到這個。 –

+0

我希望任何成熟的編譯器在編譯過程中(在這兩種情況下)都可以進行劃分,如果被告知要完全優化。 – alk

回答

4

通常您可以讓編譯器向您顯示生成的彙編代碼。使用Visual C++,你可以使用/Fa<file>選項。 gcc-S選項。

至於你的問題:大多數編譯器應該預先計算常量表達式,至少在優化級別高於O0

讓我們與您的示例方案,請參閱:

#define COUNT(x)   sizeof(x)/sizeof(x[0]) 
int data[] = {1, 2, 3, 4, 5}; 
int count = COUNT(data); 

cl /c /Fascenario1.asm scenario1.c產量編譯:

... 
PUBLIC _data 
PUBLIC _count 
_DATA SEGMENT 
_data DD 01H 
    DD 02H 
    DD 03H 
    DD 04H 
    DD 05H 
_count DD 05H 
_DATA ENDS 
END 

你看到count值接近尾聲,它的的確5.因此,編譯器計算該值甚至沒有優化開啓。

你的第二方案:

#define TOTAL   32 
#define EACH    4 
int count = (TOTAL/EACH); 

產生

... 
PUBLIC _count 
_DATA SEGMENT 
_count DD 08H 
_DATA ENDS 
END 

其中表達預先計算爲好。

當編譯時常量通過時,編譯器甚至可以評估更復雜的表達式的情況並不少見。作爲一個例子,我曾經研究過交換兩個整數的三種不同方式的代碼,一旦我對編譯器進行了優化,只是完全拋棄了對swap方法的調用,用已經交換的值替換了我的測試printf的參數。

+0

注意,C編譯器應該預先計算任何常量表達式,以便編譯像'int x [expression];'這樣的代碼,以便它們可以在任何優化級別執行。 – Vovanium