在C文件中,我们是否可以不使用#ifdef __cplusplus而使用extern "C"呢?

10

为什么在需要定义为C函数的函数中不应该指定extern "C"?如果将文件作为C源代码进行编译,这对编译器会有什么影响?

如果没有对C编译器产生影响,那么我们是否可以通过删除#ifdef __cplusplus检查的方式在头文件中定义函数,如下所示:

extern "C" {
    int MyFunc();
}

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

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

2个回答

22

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

2
如果您将源文件编译为C语言,它将“不会”识别“extern C”,通常会导致编译错误。
如果您将源文件编译为C ++,它将识别“extern C”,并且正确的名称将被链接。
因此,您只能可靠地使用它来指定编译为C ++ 的文件的C语言符号名称。
如果您将源文件编译为C和C ++,或者您的接口面向C和C ++客户端,则需要以某种方式指定这一点,以便客户端在链接时获得正确的符号(等等)。
相关:您可以编写“extern C ++”-用于C ++翻译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接