根据C ++ 17标准草案

时间:2017-02-01 11:42:54

标签: c++ language-lawyer iso c++17 linkage

来自C++17 Standard Draft § 3.5.6

  

块作用域中声明的函数的名称以及块作用域extern声明的变量的名称   宣言有联系。 如果有一个具有相同名称和链接的实体的可见声明   键入,忽略在最内层的封闭命名空间范围之外声明的实体,块范围声明   声明该实体并接收先前声明的链接。如果不止一个这样的话   匹配实体,程序格式错误。否则,如果未找到匹配的实体,则为块范围实体   接收外部链接

此外,标准中还提供了一个示例:

static void f();
static int i = 0;              // #1
void g() {
    extern void f();          // internal linkage
    int i;                    // #2 i has no linkage
    {
        extern void f();      // internal linkage
        extern int i;         // #3 external linkage
    }
}

第三个函数声明extern void f()是否收到:

  • external链接(由于前面的extern void f()声明)
  • internal链接(因为上面的块范围中的f()的第二个声明从f()全局命名空间中的::声明接收内部链接
  • 或者是因为有更多的"多个这样的匹配 实体" ?

编辑

的main.cpp

#include <iostream>

extern void g();
void f() { std::cout << "main f() called" << std::endl; }

int main(){
    g(); 
    return 0; 
}  

test.cpp

#include <iostream>

static void f() { std::cout << " test f() called" << std::endl; }
void g() {
    extern void f(); 
    {
        extern void f(); 
        f(); 
    }
}
g()的{​​{1}}函数中调用

main() 使用main.cpp

编译
  

g ++ -std = c ++ 14 -Wall main.cpp test.cpp

打印:

  

主要的f()叫

因此,gcc显然会将gcc 5.4.0内的f()调用g()链接(调用external文件中提供的定义)。标准中的示例中的注释是错误的(main.cpp的函数声明没有内部链接)或来自#3的编译器错误。

1 个答案:

答案 0 :(得分:0)

我不明白你的困惑。最里面的封闭命名空间范围是global namespace的范围;第一个和第二个声明在类型和名称中匹配,因此外部块范围声明只继承全局声明的链接(由于static说明符而在内部)。第二个块范围声明与第一个相关联;你明白了。