我们可以在没有#ifdef __cplusplus的C文件中使用extern“C”吗?

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

如果对C编译器没有影响,我们#ifdef __cplusplus删除#ifdef __cplusplus检查来在头文件中定义一个函数,如下所示:

 extern "C" { int MyFunc(); } 

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

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

构造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 

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

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

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

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

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