2012-02-29 46 views
6

为什么不应该extern "C"对于需要被定义为C函数的函数来指定?将文件编译为C源代码时对编译器有什么影响?我们可以在没有#ifdef __cplusplus的情况下在C文件中使用extern“C”吗?

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

extern "C" { 
    int MyFunc(); 
} 

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

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

回答

13

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

谢谢。我不知道这是一个C++构造。 – Alexander 2012-02-29 12:31:22

2

如果编译源文件为C,它会承认extern "C",并会通常会导致编译错误。

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

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

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

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

相关问题