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

时间:2012-02-29 12:20:23

标签: c++ c extern-c

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

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

extern "C" {
    int MyFunc();
}

An answer to another question说需要#ifdef,但我不明白为什么:

  

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

2 个答案:

答案 0 :(得分:17)

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

答案 1 :(得分:2)

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

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

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

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

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

相关问题