来自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
的编译器错误。
答案 0 :(得分:0)
我不明白你的困惑。最里面的封闭命名空间范围是global namespace的范围;第一个和第二个声明在类型和名称中匹配,因此外部块范围声明只继承全局声明的链接(由于static
说明符而在内部)。第二个块范围声明与第一个相关联;你明白了。