C++ Extern在C+中使用了两次+;

C++ Extern在C+中使用了两次+;,c++,extern,extern-c,C++,Extern,Extern C,我对链接过程中发生的事情非常好奇,在我研究这一领域的过程中,我刺穿了这段代码 #ifdef __cplusplus extern “C” { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif 代码位于某个头文件中,其中包含一个程序的.c和.cpp源文件。它是一个函数的声明,然后在.cpp文件中定义。它为什么有效?我的意思是,在编译.cpp文件的过程中,这将变成 extern "C" { ext

我对链接过程中发生的事情非常好奇,在我研究这一领域的过程中,我刺穿了这段代码

#ifdef __cplusplus
extern “C” { 
#endif

extern double reciprocal (int i);

#ifdef __cplusplus
}
#endif
代码位于某个头文件中,其中包含一个程序的.c和.cpp源文件。它是一个函数的声明,然后在.cpp文件中定义。它为什么有效?我的意思是,在编译.cpp文件的过程中,这将变成

extern "C" {
    extern double reciprocal (int i);
}

外部函数都使函数在全局范围内可见,并将函数名的C++风格转换为C函数。但也有一个内在的外在因素。函数是否被外加两次?

< P> C++语言对添加新关键字过敏,因此有些被重用以表示不同的事物。code>extern是这些重复使用的关键字之一。它有:

  • 外部链接-变量或函数在其他地方定义
  • 语言链接-变量或函数以“外部”语言定义
  • 显式模板实例化声明
  • 在本例中,您使用的是1和2<代码>外部“C”声明代码具有
    “C”
    链接,而不是默认的
    “C++”
    链接。这也意味着外部链接,所以在纯C++代码中,你可以只写:

    extern "C" {
        double reciprocal (int i);
    }
    
    交互
    将自动标记为
    外部
    。添加额外的
    extern
    无效,并且对于没有
    extern“C”
    包装的C版本是必需的

    请注意,如果您使用的是单一声明版本的
    extern“C”
    ,则使用第二个
    extern
    无效:

    extern "C" extern double reciprocal (int i);
    
    由于不需要第二个
    extern
    ,正确的声明如下:

    extern "C" double reciprocal (int i);
    

    忽略预处理
    #ifdef
    s,只看第二个代码段,前者是语言链接,主要目的是将其中的一些实体(函数类型,以及带有外部链接和变量的函数名和变量)链接到C语言,一个主要的影响是这些实体将不会有损坏的名称,而且将被放置在全局名称空间中(因为在C ABI中没有名称空间)。。。。。。内部
    extern
    不是语言链接说明符,而是存储类说明符,它不会影响这两者之间的协同作用,因为即使没有
    extern
    interactive也已经有了外部链接(这反过来意味着它有语言链接,使得它有可能链接其他语言的翻译单元)。“[…]和互惠将自动标记为
    extern
    ”-我不认为这是准确的,什么是“标记的
    extern
    ”即使在这种情况下,正如我们刚才所说的:“代码> ExtNe/Cord>关键字在C++中被严重重载了,语言链接块只是应用C语言链接到例如由具有外部链接的支撑块所包围的函数名,它不会自动标记为<代码> ExtXN/COD>。或者这样一个名称,类似于用
    extern“C”
    标记名称。作为一个(人为的)练习,我们甚至可以将
    interactive
    声明为
    static
    ,之后
    extern“C”
    块对该特定函数名没有影响,因为它不再具有外部链接。@dfri是的,您甚至不需要将其标记为静态,函数的
    extern“C”
    声明必须是第一个声明:“在使用语言规范声明函数后,可以在没有链接规范的情况下重新声明函数,第二个声明将重用第一个语言链接。相反,如果第一个声明没有语言链接,则假定为“C++”,使用另一种语言重新声明是错误的。“:我的示例应用于
    extern“C”{declaration seq(可选)}
    ,它本身不是一个声明,而是应用语言链接。例如,如果
    declaration seq
    中的一个函数声明用
    static
    标记,
    extern“C”{…}”
    block不会对其应用C语言链接。我相信您的建议涵盖了
    extern“C”{…}
    block中声明之外的重新声明,或者在使用at声明语言链接表单
    extern“C”声明时
    。gcc仍然在此处应用C链接: