为什么不应为需要定义为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
检查。
答案 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 ++翻译。