預定義的巨集

預定義的巨集是編譯器定義的巨集(與原始檔中的使用者定義相反)。使用者不得重新定義或定義這些巨集。

以下巨集由 C++標準預定義:

  • __LINE__ 包含此巨集使用的行的行號,可以通過 #line 指令進行更改。
  • __FILE__ 包含此巨集使用的檔案的檔名,可以通過 #line 指令進行更改。
  • __DATE__ 包含檔案編譯的日期(採用 Mmm dd yyyy 格式),其中 Mmm 的格式就像通過呼叫 std::asctime() 獲得的那樣。
  • __TIME__ 包含檔案編譯的時間(以 hh:mm:ss 格式)。
  • __cplusplus 由(符合)C++編譯器在編譯 C++檔案時定義。它的值是編譯器完全符合的標準版本,即用於 C++ 98 和 C++ 03 的 199711L,用於 C++ 11 的 201103L 和用於 C++ 14 標準的 201402L

Version >= C++ 11

  • 如果實現是託管的,則 __STDC_HOSTED__ 定義為 1 ,如果是獨立的,則定義為 0

Version >= C++ 17

  • __STDCPP_DEFAULT_NEW_ALIGNMENT__ 包含一個 size_t 文字,這是用於調整對齊 - 不知道 operator new 的對齊方式。

此外,允許通過實現預定義以下巨集,並且可能存在也可能不存在:

  • __STDC__ 具有依賴於實現的含義,通常僅在將檔案編譯為 C 時定義,以表示完全符合 C 標準。 (或者從不,如果編譯器決定不支援這個巨集。)

Version >= C++ 11

  • __STDC_VERSION__ 具有依賴於實現的含義,其值通常是 C 版本,類似於 __cplusplus 是 C++版本。 (如果編譯器決定不支援此巨集,則甚至不定義。)
  • __STDC_MB_MIGHT_NEQ_WC__ 定義為 1,如果基本字符集的窄編碼的值可能不等於其寬對應的值(例如,如果 (uintmax_t)'x' != (uintmax_t)L'x'
  • 如果 wchar_t 編碼為 Unicode,則定義 __STDC_ISO_10646__,並以 yyyymmL 的形式擴充套件為整數常量,表示支援的最新 Unicode 版本。
  • __STDCPP_STRICT_POINTER_SAFETY__ 定義為 1,如果實現具有嚴格的指標安全性 (否則它已經放鬆了指標安全性
  • __STDCPP_THREADS__ 定義為 1,如果程式可以有多個執行執行緒(適用於獨立實現 - 託管實現總是可以有多個執行緒)

還值得一提的是 __func__,它不是一個巨集,而是一個預定義的函式區域性變數。它包含它所使用的函式的名稱,作為實現定義格式的靜態字元陣列。

除了那些標準的預定義巨集之外,編譯器還可以擁有自己的一組預定義巨集。必須參考編譯器文件來學習它們。例如:

一些巨集只是為了查詢某些功能的支援:

#ifdef __cplusplus // if compiled by C++ compiler
extern "C"{ // C code has to be decorated
   // C library header declarations here
}
#endif

其他對除錯非常有用:

Version >= C++ 11

bool success = doSomething( /*some arguments*/ );
if( !success ){
    std::cerr << "ERROR: doSomething() failed on line " << __LINE__ - 2
              << " in function " << __func__ << "()"
              << " in file " << __FILE__
              << std::endl;
}

還有其他一些簡單的版本控制:

int main( int argc, char *argv[] ){
    if( argc == 2 && std::string( argv[1] ) == "-v" ){
        std::cout << "Hello World program\n"
                  << "v 1.1\n" // I have to remember to update this manually
                  << "compiled: " << __DATE__ << ' ' << __TIME__ // this updates automagically
                  << std::endl;
    }
    else{
        std::cout << "Hello World!\n";
    }
}