首页 文章

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

提问于
浏览
7

为什么不应为需要定义为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 回答

  • 2

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

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

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

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

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

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

相关问题