首页 文章

为什么这些带外部联动的名称不能表示同一个实体?

提问于
浏览
1

请考虑以下代码段:

#include <iostream>

int a;
void address_of_a(void) {
    std::cout << &a << std::endl;
}

namespace N {
    int a;
    void address_of_a(void) {
        std::cout << &a << std::endl;
    }   
};

int main(void) {
    address_of_a();
    N::address_of_a();
    return 0;
}

The global namespace and named namespace N are given external linkage 因为来自N4567的3.5 [basic.link]第4段说明了这一点

未命名的命名空间或直接或间接在未命名的命名空间内声明的命名空间具有内部链接 . 所有其他名称空间都有外部链接...

此外, ::a and N::a are also given external linkage 因为它们不适用于3.5 [basic.link]第3段,

具有命名空间范围(3.3.6)的名称具有内部链接,如果它是显式声明为静态的变量,函数或函数模板的名称;或者,非易失性const限定类型的变量,既未明确声明为extern,也未声明为具有外部链接;或匿名工会的数据成员 .

但到3.5 [basic.link]第4段,

...具有名称空间范围的名称,如果它是变量的名称,则上面没有给出内部链接的名称与封闭名称空间具有相同的链接;要么 ...

这意味着说 they inherit the same linkage(=external linkage) as the global namespace and N . 总之, they shall denote the same entity 因为3.5 [basic.link]第9段说的那样

两个相同的名称(第3条)和在不同范围内声明的名称应表示相同的变量,函数,类型,枚举器,模板或命名空间,如果两个名称都具有外部链接或两个名称都具有内部链接并在同一翻译单位;和......

但是,它们似乎表示不同的实体,因为它们的地址不一致 . 这是为什么?

1 回答

  • 4

    见第二个子弹 .

    两个相同的名称(第3条)和在不同范围内声明的名称应表示相同的变量,函数,类型,枚举器,模板或命名空间,如果两个名称都具有外部链接,或者两个名称都具有内部链接并且在相同的翻译单位;并且这两个名称都指向同一名称空间的成员或同一类的成员,而不是继承 . 当两个名称都表示函数时,函数的参数类型列表(8.3.5)是相同的;当两个名称都表示功能模板时,签名(14.5.6.1)是相同的 .

    ::aN::a 不引用相同名称空间的成员,因此它们不表示相同的变量 .

相关问题