代码之家  ›  专栏  ›  技术社区  ›  Alex B

常规命名空间内匿名命名空间内的符号链接

  •  14
  • Alex B  · 技术社区  · 15 年前

    在C++中,将一个函数或变量放在匿名命名空间中使它的链接处于内部,也就是声明它一样。 static 在文件级,但习惯性C++。

    普通名称空间中的匿名名称空间如何?它仍然保证内部联系吗?

    // foo.cpp
    
    void func1() {
        // external linkage
    }
    
    static void func2() {
        // internal linkage
    }
    
    namespace {
        void func3() {
            // internal linkage
        }
    }
    
    namespace ns1 {
        void func4() {
            // external linkage
        }
    
        namespace {
            void func3() {
                // still internal linkage?
            }
        }
    }
    
    3 回复  |  直到 15 年前
        1
  •  12
  •   Community Mohan Dere    9 年前

    C++ 11(草案N33 37)第3.5/4段:(强调矿井)

    未命名命名空间或直接或间接在未命名命名空间中声明的命名空间具有内部链接 . 所有其他命名空间都有外部链接。具有未在上面提供内部链接的命名空间范围的名称与封闭命名空间具有相同的链接(如果它是的名称)

    变量;或

    _

    “命名类”(第9条),或在typedef声明中定义的未命名类,其中该类具有typedef名称用于链接(7.1.3);或

    命名枚举(7.2)或在typedef声明中定义的未命名枚举,其中枚举具有typedef名称以进行链接(7.1.3);或

    属于具有链接的枚举的枚举器;或

    “模板”。

    这可以确保任何未命名的命名空间都具有内部链接。

    普通名称空间中的匿名名称空间如何?它仍然保证内部联系吗?

    虽然在命名(正常)命名空间内,它是一个未命名的(匿名)命名空间,因此保证按照C++ 11标准具有内部链接。


    在匿名命名空间中放置一个函数或变量使它的链接处于内部,也就是说在文件级声明它是静态的,但是习惯C++。

    在C++ 11中的用法 static 在这种情况下 未预制 ;尽管 unnamed namespace is a superior alternative to static , there're instances where it fails 哪种方法可以补救 静止的 ; inline namespace was introduced in C++11 解决这个问题。

        2
  •  15
  •   James McNellis    15 年前

    匿名命名空间中的实体不一定有内部链接;它们实际上可能有外部链接。

    由于未命名的命名空间的名称对于编译它的翻译单元是唯一的,所以您不能从该翻译单元外部引用其中声明的实体,而不管它们的链接是什么。

    C++标准表示(C++ 03 7.3.1.1注释82):

    尽管未命名命名空间中的实体可能具有外部链接,但它们实际上是由其翻译单元唯一的名称限定的,因此从任何其他翻译单元都看不到。

        3
  •  5
  •   Chubsdad    15 年前

    $3.5/3-“有名称空间的名称 范围(3.3.6)具有内部联系,如果 它的名字是

    变量, 函数或函数模板 明确声明为静态;或,

    _ 显式声明的变量 const和都没有显式声明 外部或以前声明具有 外部联动装置;或

    “数据成员” 一个匿名的联盟。

    所以,我怀疑程序中的任何名称“func3”和“func4”是否有内部链接。它们有外部连接。然而,这只是因为他们不能从其他翻译单位根据詹姆斯的引述。