无法理解[basic.link] / 6 C ++ 14的例子中的声明#3

时间:2015-04-27 19:15:26

标签: c++ declaration language-lawyer c++14 extern

[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行的声明中介绍。 - 例子]

我对这一段有两点评论:

  1. 全局范围内的static int i = 0;声明在包含声明extern int i;(#3)的块内可见。因此,我们只能说后一种宣言具有外部联系,即我们不能将其与宣言#1联系起来。
  2. 否则,如果声明#3认为声明static int i;可见,则根据段落中的文本,块范围声明声明同一实体并接收先前声明的链接,即,内部联系,而不是外部联系,如示例中所述。
  3. 我在这里缺少什么?

1 个答案:

答案 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说:

  

如果在翻译单元内,同一标识符同时显示内部和外部   联系,行为未定义。