[basic.link] / 6
在块作用域中声明的函数的名称和a的名称 由块作用域
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 } }
此程序中有三个名为
i
的对象。具有内部链接的对象由全局范围内的声明引入(第1行),具有自动存储持续时间的对象并且没有由第2行上的声明引入的链接,以及具有静态存储持续时间和外部链接的对象< / strong>在第3行的声明中介绍。 - 例子]
我对这一段有两点评论:
static int i = 0;
声明在包含声明extern int i;
(#3)的块内可见不。因此,我们只能说后一种宣言具有外部联系,即我们不能将其与宣言#1联系起来。static int i;
可见,则根据段落中的文本,块范围声明声明同一实体并接收先前声明的链接,即,内部联系,而不是外部联系,如示例中所述。我在这里缺少什么?
答案 0 :(得分:9)
这取决于active issue 426,其中包含:
3.5 [basic.link]第6段中的一个例子创建了两个文件范围 具有相同名称的变量,一个具有内部链接,另一个具有 外部
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 } }
这真的是我们想要的吗? C99有6.2.2.7/7,它给出了undefined 具有标识符的行为与内部和外部一起出现 在同一翻译单元中的联系。 C ++似乎没有 等效。
最初的提议是将其定义为未定义的行为:
我们同意这是一个错误。我们建议留下这个例子 更改注释以指示第//行有未定义的行为, 和其他地方添加一个规范性规则,给出这种情况未定义 行为。
但最后两条评论说:
根据3.5 [basic.link]第9段,两个变量一起使用 所提出的例子中的联系不是“同一个实体”,因为它们 没有相同的联系。还需要其他一些配方 描述这两个变量之间的关系。
和
CWG决定用这个做一个程序会更好 一种联系不匹配形成不良而不是未定义 行为。
最新的评论没有提出新的措辞,自2006年以来一直没有更新,所以我们可以说当前的想法是这是不正确的。
作为参考,C99标准草案6.2.2.7/7
说:
如果在翻译单元内,同一标识符同时显示内部和外部 联系,行为未定义。