對於預定義宏,相信大家並不陌生。為了方便處理一些有用的資訊,前處理器定義了一些預處理識別符號,也就是預定義宏。預定義宏的名稱都是以“__”(兩條下劃線)開頭和結尾的,如果宏名是由兩個單詞組成,那麼中間以“_”(一條下劃線)進行連線。並且,宏名稱一般都由大寫字元組成。
在日常專案程式設計中,預定義宏尤其對多目標平台程式碼的編寫通常具有重大意義。通過預定義宏,程式設計師使用“#ifdef”與“#endif”等預處理指令,就可使平台相關程式碼只在適合於當前平台的程式碼上編譯,從而在同一套程式碼中完成對多平台的支援。從這個意義上講,平台資訊相關的宏越豐富,程式碼的多平台支援越準確。
標準 C 語言提供的一些標準預定義宏如表 1 所示。
表 1 常用的標準預定義宏
宏 |
描 述 |
__DATE__ |
丐前原始檔的編澤口期,用 “Mmm dd yyy”形式的字串常數表示 |
__FILE__ |
當前原始檔的名稱,用字串常數表示 |
__LINE__ |
當前源義件中的行號,用十進位制整數常數表示,它可以隨#line指令改變 |
__TIME__ |
當前原始檔的最新編譯吋間,用“hh:mm:ss”形式的寧符串常數表示 |
__STDC__ |
如果今前編澤器符合ISO標準,那麼該宏的值為1,否則未定義 |
__STDC_VERSION__ |
如果當前編譯器符合C89,那麼它被定義為199409L;如果符合C99,那麼它被定義為199901L:在其他情況下,該宏為宋定義 |
__STDC_HOSTED__ |
(C99)如果當前是宿主系統,則該宏的值為1;如果當前是獨立系統,則該宏的值為0 |
__STDC_IEC_559_ |
(C99)如果浮點數的實現符合IEC 60559標準時,則該宏的值為1,否則為未定義 |
__STDC_IEC_559_COMPLEX__ |
(C99)如果複數運算實現符合IEC60559標準時,則該宏的伉為1,否則為未定義 |
__STDC_ISO_10646__ |
(C99 )定義為長整型常數,yyyymmL表示wchai_t值遵循ISO 10646標準及其指定年月的修訂補充,否則該宏為未定義 |
除標準 C 語言提供的標準宏之外,各種編譯器也都提供了自己的自定義預定義宏。可以通過表 2 所示的指令來檢視不同編譯器對預定義宏的支援情況。
表 2 不同編譯器的預定義宏檢視指令
編譯器 |
宏指令(c) |
宏指令(C++) |
Clang/LLVM |
clang -dM -E -x c /dev/null |
clang++ -dM -E -x C++ /dev/null |
GNU GCC/G++ |
gcc -dM -E -x c /dev/null |
g++ -dM -E -x C++ /dev/null |
Hewlett-Packard C/aC++ |
cc -dM -E -x c /clev/null |
aCC -dM -E -x C++ /dev/null |
IBM XL C/C++ |
xlc -qshowmacros -E /dev/null |
xlc++ -qshowmacros -E /dev/null |
Intel ICC7ICPC |
icc -dM -E -x c /dev/null |
icpc -dM -E -x C++ /dev/null |
Oracle Solaris Studio |
cc -xduinpmacros -E /dev/null |
CC -xduinpmacros -E /clev/null |
Portland Group PGCC/PGCPP |
pgcc -dM -E |
|
圖 3 顯示了 GCC 編譯器預定義宏的檢視結果。雖然各種編譯器的預定義宏不盡相同,但是一般都會支援“__DATE__、__FILE__、__LINE__與__TIME__”這 4 種預定義宏。
圖 3 檢視 GCC 預定義宏