C語言預定義的宏

2020-07-16 10:04:28
凡是遵循 ISO C 標準的編譯器都必須定義下面 7 個宏。這些宏的名稱都是以兩個下劃線開始,以兩個下劃線結束

(1) __DATE__

它的替換文字是一個包含編譯日期的字串字面量,日期格式為"Mmm dd yyyy"(例如:"Mar 192006")。如果天數小於 10,就在日的前面新增一個空格符。

(2) __FILE__

一個含有當前原始碼檔名稱的字串字面量。

(3) __LINE__

一個整數常數,其值是當前原始檔(包含宏 __LINE__ 參照的檔案)的行號,從檔案頭開始算起。

(4) __TIME__

一個包含編譯時間的字串字面量,格式為"hh:mm:ss"(例如:"08:00:59")。

(5) __STDC__

整數常數 1,表示該編譯器遵循 ISO C 標準。

(6) __STDC_HOSTED__

如果當前實現版本是宿主環境下的實現版本,該宏為整數常數 1;否則,為常數 0。

(7) __STDC_VERSION__

如果編譯器支援 1999 年 1 月的 C99 標準,則該宏為長整數常數 199901L。如果編譯器支援 2011 年 12 月的 C11 標準,則該宏為長整數常數 201112L。

#line 命令可影響 __FILE__ 和 __LINE__ 宏的值。其他預定義的宏則完全不受任何外部因素影響,在整個編譯過程中都是常數。

常數 __STDC_VERSION__ 的值在未來新的 C 語言國際標準中會被調整。

從 C99 標準開始,C 程式或者在宿主環境(hosted)中執行,或者在獨立環境(freestanding)中執行。大多數 C 程式都在宿主環境中執行,也就是說,C 程式在作業系統的控制和支援之下執行。在這種情況下,常數 __STDC_HOSTED__ 的值是 1,且擁有完整的標準庫。

如果程式在獨立環境中執行,則沒有作業系統的支援,因此只需要最少的標準庫資源就可以使用。

在特定條件下被預定義的宏

與前面列舉的宏不同,下面的標準宏只有在特定的條件下才會被預定義。如果下面這些宏中有任何一個被定義,表示該實現版本支援某個 IEC 或 ISO 的標準:

(1) __STDC_IEC_559__

如果實現版本的浮點實數算術符合 IEC 60559 標準,則該常數值為 1。

(2) __STDC_IEC_559_COMPLEX__

如果實現版本的浮點複數算術符合 IEC 60559 標準,則該常數值為 1。

(3) __STDC_ISO_10646__

該長整數常數代表 yyyymmL 格式的一個日期(例如:199712L)。如果該常數值被定義,那麼型別為 wchar_t 的寬字元編碼符合 ISO/IEC 10646 標準,且符合包含到該宏所定義日期為止所制訂的所有增補和修訂。

C11 標準新增了下面可選的宏:

(1) __STDC_MB_MIGHT_NEQ_WC__

如果一個在基本字元集中的字元,不強制要求它以 wchar_t 物件的編碼值等於它對應的字元常數,則該常數值為 1。

(2) __STDC_UTF_16__

如果型別 char16_t 以 UTF-16 方式編碼,則該常數值為 1。如果該型別使用其他編碼方式,則該宏未定義。

(3) __STDC_UTF_32__

如果型別 char32_t 以 UTF-32 方式編碼,則該常數值為 1。如果該型別使用其他編碼方式,則該宏未定義。

(4) __STDC_ANALYZABLE__

如果當前實現版本支援 C11 標準中附錄 L 中對執行錯誤的分析,則該常數值為 1。

(5) __STDC_LIB_EXT1__

如果當前實現版本支援 C11 標準中附錄 K 中關於邊界檢查的新函數,則該常數值為 201112L。這些新函數名稱均以 _s 結尾。

(6) __STDC_NO_ATOMICS__

如果當前實現版本沒有包括針對於原子記憶體存取操作的型別與函數(不存在標頭檔案 stdatomic.h),則該常數值為 1。

(7) __STDC_NO_COMPLEX__

如果當前實現版本不支援複數算術運算(不存在標頭檔案 complex.h),則該常數值為 1。

(8) __STDC_NO_THREADS__

如果當前實現版本不支援多執行緒(不存在標頭檔案 threads.h),則該常數值為 1。

(9) __STDC_NO_VLA__

如果當前實現版本不支援可變長度陣列,則該常數值為 1。

宏名稱 __cplusplus 專為 C++ 編譯器保留,因此,當編譯 C 原始檔時,不可以定義名稱為 __cplusplus 的宏。