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