标准N3242(C++ 11草案)和N3797(C++ 14草案)都有相同的段落.
§3.5计划和联系[basic.link]
6
在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.[例如:
Run Code Online (Sandbox Code Playgroud)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 } }在这个程序中有三个名为i的对象.具有内部链接的对象由全局范围内的声明引入(第1行),具有自动存储持续时间的对象并且没有由第2行上的声明引入的链接,以及具有静态存储持续时间和由声明引入的外部链接的对象在第3行. - 结束例子]
我觉得i对象示例有问题,它不支持之前段落中的内容,对吧?在我看来,它必须是两个i对象,一个具有内部链接(#1和#3),另一个没有链接(#2).我对么?这是标准中的错误,这个例子是错的吗?
相比之下,标准N4659(C++ 17草案)在我看来更正确.
§6.5计划和联系[basic.link]
6
在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.如果在翻译单位内,同一实体被宣布具有内部和外部联系,则该程序是不正确的.[例如:
Run Code Online (Sandbox Code Playgroud)static void f(); static int i = 0; // #1 void g() …