2010-02-08 56 views

回答

235

是的,使用-E -dM選項代替-c。 實施例(它們輸出到stdout):

gcc -dM -E - < /dev/null 

gcc manual

代替正常輸出的,生成 所有 期間定義的宏`的#define」的指令的列表 執行預處理器, 包括預定義的宏。此 爲您提供了一種查找 預處理器版本中預定義的 的方法。假設你有沒有 文件foo.h中,命令

touch foo.h; cpp -dM foo.h 

將顯示所有的預定義宏。

如果使用不帶-E選項的-dM,則將 -dM解釋爲-fdump-rtl-mach的同義詞。

+2

GCC。 – Pavel 2014-01-12 01:29:33

+3

@Pavel然後你可以使用一個空文件,使用gcc或預處理器 - cpp。 – philant 2014-01-12 09:16:17

+15

我添加了一個更便攜的方法作爲替代答案:'echo | gcc -dM -E-'也適用於Windows。 – Pavel 2014-01-13 20:30:16

71

我通常做這種方式:

$ gcc -dM -E - < /dev/null 

注意一些預處理定義是依賴於命令行選項 - 您可以通過添加相關的選項,上面的命令行測試這些。例如,看哪個SSE3/SSE4選項是默認啓用的:

$ gcc -dM -E - < /dev/null | grep SSE[34] 
#define __SSE3__ 1 
#define __SSSE3__ 1 

,然後在指定-msse4比較這:

$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34] 
#define __SSE3__ 1 
#define __SSE4_1__ 1 
#define __SSE4_2__ 1 
#define __SSSE3__ 1 

同樣可以看到哪些選項兩套不同的之間的差異命令行選項,例如比較預處理定義優化級別-O0(無)和-O3(滿):

$ gcc -dM -E -O0 - </dev/null> /tmp/O0.txt 
$ gcc -dM -E -O3 - </dev/null> /tmp/O3.txt 
$ sdiff -s /tmp/O0.txt /tmp/O3.txt 
#define __NO_INLINE__ 1  < 
           > #define __OPTIMIZE__ 1 
35

遲到的回答 - 我發現其他答案有用 - 並想增加一點額外的。


我如何轉儲預處理宏從一個特定的頭文件來嗎?

echo "#include <sys/socket.h>" | gcc -E -dM - 

我特別想看看SOMAXCONN被定義爲我的系統上。我知道我可以打開標準頭文件,但有時我必須搜索一下才能找到頭文件位置。相反,我可以只用這一個班輪:

$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN 
#define SOMAXCONN 128 
$ 
15

更是很好地工作在Windows便攜式辦法(那裏沒有的/ dev/null的)或Linux:

echo | gcc -dM -E - 
+5

@rubenvb這是無關緊要的。問題的關鍵在於至少在windows和unix上具有相同的cmd行。如果你使用'NUL',你又回到了原來的狀態:它不適用於沒有它的系統。 – Pavel 2014-01-29 18:42:12

+0

爲C++添加完整的答案,適用於Windows和Linux(儘管'sort'行爲有點不同):'echo | gcc -x C++ -std = C++ 17 -dM -E - |排序' – Xeverous 2017-07-30 11:56:49

25

簡單的方法( gcc -dM -E - < /dev/null)適用於gcc,但g ++失敗。最近我需要測試C++ 11/C++ 14功能。其相應宏名稱的建議公佈於https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations。但是:

g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates 

總是失敗,因爲它默默調用C-驅動程序(彷彿gcc調用)。你可以通過比較它的輸出與gcc的輸出或者添加一個特定於g ++的命令行選項(如-std = C++ 11)來發現錯誤消息cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C

因爲(非C++)GCC將從未支持「模板別名」(見http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf),您必須添加-x c++選項強制C++編譯器的調用(現金使用-x c++選項,而不是一個空的假人文件去yuyichao,見下文):

g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates 

,將沒有輸出,因爲克++(修訂版4.9.1,默認爲-STD = GNU ++ 98)不啓用默認爲C++ 11的功能。爲了這樣做,使用

g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates 

這最終產生

#define __cpp_alias_templates 200704 

指出的是G ++ 4.9.1並當與-std=c++11調用支持 「模板別名」。

+6

您不必使用虛擬文件。 GCC支持'-x'參數,所以'g ++ -x C++ -dM -E -std = C++ 11 - yuyichao 2015-02-16 03:56:03

+0

@yuyichao謝謝,這使它更容易使用。我不知道-x選項。 Upvoted您的評論,並將其整合到原來的答案。 – hermannk 2015-02-17 07:43:30

0

在一個複雜構建系統的大項目中工作,並且很難直接獲取(或修改)gcc/g ++命令時,還有另一種方法可以查看宏擴展的結果。 簡單地重新定義宏,你會得到輸出類同如下:對系統中存在其中/ dev/null表示沒有

file.h: note: this is the location of the previous definition 
#define MACRO current_value