cplusplus 用於在 C 程式碼編譯中使用 C 程式碼修改的 C 外部程式碼

有些情況下,由於語言不同,包含檔案必須從前處理器生成不同的輸出,具體取決於編譯器是 C 編譯器還是 C++編譯器。

例如,函式或其他外部函式在 C 原始檔中定義,但在 C++原始檔中使用。由於 C++使用名稱修改(或名稱修飾)來生成基於函式引數型別的唯一函式名稱,因此 C++原始檔中使用的 C 函式宣告將導致連結錯誤。C++編譯器將使用 C++的名稱 mangling 規則修改編譯器輸出的指定外部名稱。結果是由於在 C++編譯器輸出與 C 編譯器輸出連結時未找到外部因素導致的連結錯誤。

由於 C 編譯器不進行名稱修改,但 C++編譯器會對 C++編譯器生成的所有外部標籤(函式名或變數名)執行操作,因此引入了預定義的前處理器巨集 __cplusplus 以允許編譯器檢測。

為了解決 C 和 C++之間外部名稱的不相容編譯器輸出的問題,巨集 __cplusplus 在 C++前處理器中定義,並且未在 C 前處理器中定義。此巨集名稱可以與條件前處理器 #ifdef 指令或 #if 一起使用 defined() 運算子來判斷原始碼或包含檔案是否正在編譯為 C++或 C.

#ifdef __cplusplus
printf("C++\n");
#else
printf("C\n");
#endif

或者你可以使用

#if defined(__cplusplus)
printf("C++\n");
#else
printf("C\n");
#endif

為了從 C++原始檔中使用的 C 編譯器編譯的 C 原始檔中指定函式的正確函式名,可以檢查 __cplusplus 定義的常量,以便使用 extern "C" { /* ... */ }; 來宣告 C 標頭檔案包含在 C++原始檔中時的外部。但是,使用 C 編譯器編譯時,不使用 extern "C" { */ ... */ };。這種條件編譯是必需的,因為 extern "C" { /* ... */ }; 在 C++中有效但在 C 中不有效。

#ifdef __cplusplus
// if we are being compiled with a C++ compiler then declare the
// following functions as C functions to prevent name mangling.
extern "C" {
#endif

// exported C function list.
int foo (void);

#ifdef __cplusplus
// if this is a C++ compiler, we need to close off the extern declaration.
};
#endif