我有一個像解決GCC轉儲定義
#define ONE 1
#define TWO 2
#define SUM (ONE+TWO)
如何傾倒SUM爲「3」,解析值代碼,在GCC 4.3或更高版本?
gcc -dM -E foo.h
似乎只是傾倒它。我如何獲得它在編譯階段插入的實際值?
我有一個像解決GCC轉儲定義
#define ONE 1
#define TWO 2
#define SUM (ONE+TWO)
如何傾倒SUM爲「3」,解析值代碼,在GCC 4.3或更高版本?
gcc -dM -E foo.h
似乎只是傾倒它。我如何獲得它在編譯階段插入的實際值?
你不能。就編譯器而言,預處理前的行printf("%d\n", SUM)
與行printf("%d\n", 1+2)
無法區分。編譯器恰好執行稱爲constant folding的優化,即使在默認的優化級別(-O0
)中,也會在運行時將結果轉換爲常量3。
看到這些優化的輸出並不是一個好方法。您可以使用-S
選項來查看生成的彙編代碼並查看看起來像什麼,但是如果您的程序比玩具大,那將是很多手動操作。您也可以使用-fdump-tree
選項之一查看分析樹(請參閱GCC手冊頁)。
我已經理解了......這首先是一個糟糕的問題。我想我必須走另一條路。感謝提供不斷摺疊的提示,這非常有用。 – gccnewbie
你不能「甩」 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;
}
有了這個例子中有沒有辦法,你能證明SUM
是3
。
與其他答案相反,這個問題絕對有解決方案,尤其是對於gcc擴展。解析gcc -dM
的輸出並生成一個包含__typeof__(MACRO) foo = MACRO;
形式的行的C文件,並從那裏開始。如果沒有__typeof__
,只需使用long double
即可處理所有算術類型。
查看編譯器生成的彙編代碼。 –
但是'SUM'不是3,它是'ONE + TWO'。宏在他們出現的地方展開,這就是他們的工作方式。在'SUM'的定義之後嘗試通過定義'ONE',將其重新定義爲不同的東西,然後將SUM插入到源中。 –