不能理解[basic.link] / 6 C ++ 14示例中的声明#3 [英] Can't understand the declaration #3 in the Example of [basic.link]/6 C++14

查看:200
本文介绍了不能理解[basic.link] / 6 C ++ 14示例中的声明#3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[basic.link] / 6


在块范围中声明的函数的名称和
的名称块范围 extern 声明的变量具有链接。
如果存在具有
相同名称和类型的链接的实体的可见声明,忽略在最内部的
外部命名空间范围之外声明的实体,块范围声明声明
同一个实体并接收先前声明的链接。如果
有多个这样的匹配实体,程序是
形式。否则,如果没有找到匹配实体,块范围
实体接收外部链接。[示例:

  static void F(); 
static int i = 0; //#1
void g(){
extern void f(); // internal linkage
int i; //#2我没有链接
{
extern void f(); // internal linkage
extern int i; //#3 external linkage
}
}

i 。具有由全局范围(行#1)中的声明引入的内部链接的对象,具有自动存储持续时间并且没有由行#2上的声明引入的链接的对象,以及具有静态存储持续时间和外部链接由第3行的声明引入。 -end example]


我有两个关于这个段落的评论:


  1. 全局范围中的 static int i = 0; 声明是在包含声明的块中可见 extern int i; (#3)。因此,我们只能说后面的声明具有外部链接,即我们不能将它与声明#1相关联。

  2. 否则,如果声明 static int i; 被声明#3视为可见,而不是根据段落中的文本,块范围声明声明相同的实体并接收先前声明的链接,即内部链接,


  3. 我在这里缺少什么?

    解决方案

    这取决于有效问题426 说:


    在3.5 [basic.link]段落6中创建了两个具有相同名称的文件范围的
    变量,一个带有内部链接,一个带有
    external。

      static void f(); 
    static int i = 0; // 1
    void g(){
    extern void f(); // internal linkage
    int i; // 2:我没有链接
    {
    extern void f(); // internal linkage
    extern int i; // 3:external linkage
    }
    }

    想? C99有6.2.2.7/7,它给出了未定义的
    行为,使得在同一翻译单元中出现具有内部和外部
    链接的标识符。 C ++似乎没有
    的等效项。


    原始提议是使其未定义的行为:


    我们同意这是一个错误。我们建议离开这个例子,但是
    改变注释以指示行// 3有未定义的行为,
    和其他地方添加一个规范规则给出这样的情况未定义的
    行为。


    但最后两个注释说:


    3.5 [basic.link]段落9中,在提出的示例中,具有
    链接的两个变量不是相同实体,因为它们
    不具有相同的链接。需要一些其他公式来描述这两个变量之间的关系。
    描述这两个变量之间的关系。


    和:


    CWG决定使用这个
    类型的链接不匹配而不是未定义的
    行为。


    最新的评论没有提出新的措辞,并且自2006年以来没有更新,所以我们可以说



    为了参考草案C99标准 6.2.2.7/7 说:


    如果在翻译单元中,同一标识符同时出现内部和外部
    链接,则该行为未定义。 / p>


    [basic.link]/6

    The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage.[ Example:

    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
        }
    }
    

    There are three objects named i in this program. The object with internal linkage introduced by the declaration in global scope (line #1), the object with automatic storage duration and no linkage introduced by the declaration on line #2, and the object with static storage duration and external linkage introduced by the declaration on line #3. —end example ]

    I have two comments about this paragraph:

    1. The static int i = 0;declaration in the global scope is not visible inside the block containing the declaration extern int i; (#3). Therefore we can only say that this latter declaration has external linkage, i.e., we can't associate it with declaration #1.
    2. Otherwise, if the declaration static int i; is considered visible by the declaration #3, than according to the text in the paragraph, the block scope declaration declares the same entity and receives the linkage of the previous declaration, that is, internal linkage, and not external linkage, as stated in the Example.

    What am I missing here?

    解决方案

    This is subject to active issue 426 which says:

    An example in 3.5 [basic.link] paragraph 6 creates two file-scope variables with the same name, one with internal linkage and one with external.

    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
          }
    }  
    

    Is this really what we want? C99 has 6.2.2.7/7, which gives undefined behavior for having an identifier appear with internal and external linkage in the same translation unit. C++ doesn't seem to have an equivalent.

    The original proposal was to make it undefined behavior:

    We agree that this is an error. We propose to leave the example but change the comment to indicate that line //3 has undefined behavior, and elsewhere add a normative rule giving such a case undefined behavior.

    but the last two comments say:

    According to 3.5 [basic.link] paragraph 9, the two variables with linkage in the proposed example are not "the same entity" because they do not have the same linkage. Some other formulation will be needed to describe the relationship between those two variables.

    and:

    The CWG decided that it would be better to make a program with this kind of linkage mismatch ill-formed instead of having undefined behavior.

    The latest comments did not propose a new wording and it has not been updated since 2006, so at best we can say the current thinking is that this is ill-formed.

    For reference the draft C99 standard 6.2.2.7/7 says:

    If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

    这篇关于不能理解[basic.link] / 6 C ++ 14示例中的声明#3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆