2011-09-27 73 views
1

我有一個像解決GCC轉儲定義

#define ONE 1 
#define TWO 2 
#define SUM (ONE+TWO) 

如何傾倒SUM爲「3」,解析值代碼,在GCC 4.3或更高版本?

gcc -dM -E foo.h似乎只是傾倒它。我如何獲得它在編譯階段插入的實際值?

+1

查看編譯器生成的彙編代碼。 –

+3

但是'SUM'不是3,它是'ONE + TWO'。宏在他們出現的地方展開,這就是他們的工作方式。在'SUM'的定義之後嘗試通過定義'ONE',將其重新定義爲不同的東西,然後將SUM插入到源中。 –

回答

2

你不能。就編譯器而言,預處理前的行printf("%d\n", SUM)與行printf("%d\n", 1+2)無法區分。編譯器恰好執行稱爲constant folding的優化,即使在默認的優化級別(-O0)中,也會在運行時將結果轉換爲常量3。

看到這些優化的輸出並不是一個好方法。您可以使用-S選項來查看生成的彙編代碼並查看看起來像什麼,但是如果您的程序比玩具大,那將是很多手動操作。您也可以使用-fdump-tree選項之一查看分析樹(請參閱GCC手冊頁)。

+0

我已經理解了......這首先是一個糟糕的問題。我想我必須走另一條路。感謝提供不斷摺疊的提示,這非常有用。 – gccnewbie

0

一種方法是停在預編譯器階段(-E)並檢查該輸出。

+1

這就是他已經做的 – Mat

+0

Doh!我錯過了! :) –

1

你不能「甩」 SUM爲3,因爲SUM不是3任何意義,它只是一個三個令牌ONE+TWO的序列。它變成什麼取決於它擴展的上下文。

宏在源代碼中出現的地方展開,宏代替只是在此之前的代幣串。

你可以這樣測試。

#include <stdio.h> 

#define ONE 1 
#define TWO 2 
#define SUM ONE+TWO 
int a = SUM; 
#undef ONE 
#define ONE 2 
int b = SUM; 

int main() 
{ 
    printf("a = %d\nb = %d\n", a, b); 
    return 0; 
} 

再舉一例:

#include <stdio.h> 
#define ONE 1 
#define TWO 2 
#define SUM ONE+TWO 
int main() 
{ 
    /* prints 6, not 2 */ 
    printf("5 - SUM = %d\n", 5 - SUM); 
    return 0; 
} 

有了這個例子中有沒有辦法,你能證明SUM3

+0

好吧,我的代碼有錯誤,如果我把它寫成'#define SUM(ONE + TWO)',會怎麼樣?它仍然打印未觸摸,但最後一個例子會顯示2.任何方式將其轉儲爲3? – gccnewbie

+0

我想我應該堅持像printf這樣的「輸出」方法,或者爲轉儲寫外部分析器。是的,我的問題最初是壞的。 – gccnewbie

1

與其他答案相反,這個問題絕對有解決方案,尤其是對於gcc擴展。解析gcc -dM的輸出並生成一個包含__typeof__(MACRO) foo = MACRO;形式的行的C文件,並從那裏開始。如果沒有__typeof__,只需使用long double即可處理所有算術類型。