10

为什么不应该extern "C"为需要定义为 C 函数的函数指定?将文件编译为 C 源代码时会对编译器产生什么影响?

如果对 C 编译器没有影响,我们不能通过删除#ifdef __cplusplus检查在下面的头文件中定义一个函数吗?

extern "C" {
    int MyFunc();
}

另一个问题的答案#ifdef需要,但我不明白为什么:

关于#2: __cplusplus 将为通过 C++ 编译器运行的任何编译单元定义。通常,这意味着 .cpp 文件和该 .cpp 文件包含的任何文件。如果不同的编译单元包含相同的 .h(或 .hh 或 .hpp 或 what-have-you),则可以在不同时间将它们解释为 C 或 C++。如果您希望 .h 文件中的原型引用 C 符号名称,则它们extern "C"在被解释为 C++ 时必须具有,而在被解释为 C 时不应具有extern "C"- 因此进行#ifdef __cplusplus检查。

4

2 回答 2

21

该构造extern "C"是 C++ 构造,C 编译器无法识别。通常,它会发出语法错误消息。

一个常见的技巧是定义一个宏,例如 EXTERN_C,根据您是使用 C 还是 C++ 编译,它会扩展为不同的东西。例如:

在一个通用的头文件中:

#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif

在其他文件中:

EXTERN_C
int MyFunc(void);
EXTERN_C_END
于 2012-02-29T12:22:37.700 回答
2

如果将源文件编译为 C,它将无法识别extern "C",并且通常会导致编译错误。

如果您将源文件编译为 C++,它将识别extern "C"链接正确的名称。

因此,您只能可靠地使用它为您编译为 C++ 的文件指定 C 符号名称。

如果您将源代码编译为 C 和 C++,或者您的接口是为 C 和 C++ 客户端设计的,则需要指定这种或另一种方式,以便客户端在链接时(等等)获得正确的符号。

相关:您可以编写extern "C++"- 用于 C++ 翻译。

于 2012-02-29T12:33:01.693 回答