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

Ale*_*x B 14 c++ namespaces anonymous linkage

在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?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 16

匿名命名空间中的实体不一定具有内部链接; 他们实际上可能有外部联系.

由于未命名的命名空间的名称对于编译它的转换单元是唯一的,因此无论它们的链接是什么,您都无法从该转换单元外部引用在其中声明的实体.

C++标准说(C++ 03 7.3.1.1/note 82):

虽然未命名的命名空间中的实体可能具有外部链接,但它们实际上由其翻译单元唯一的名称限定,因此永远不会从任何其他翻译单元中看到.

  • 快速跟进:您是否知道如果内部链接以某种方式帮助编译器为其优化做出更好的代码转换决策,或者它是否是一个非问题? (2认同)

leg*_*s2k 12

C++ 11(草案N3337)§3.5/ 4 :(强调我的)

未命名的命名空间或在未命名的命名空间中直接或间接声明的命名空间具有内部链接.所有其他名称空间都有外部链接.具有名称空间作用域的名称上面没有给出内部链接,如果是名称,则具有与封闭名称空间相同的链接

- 一个变量; 要么

- 一个功能; 要么

- 命名类(第9节),或在typedef声明中定义的未命名类,其中类具有用于链接目的的typedef名称(7.1.3); 要么

- 命名枚举(7.2),或在typedef声明中定义的未命名枚举,其中枚举具有用于链接目的的typedef名称(7.1.3); 要么

- 属于具有链接的枚举的枚举器; 要么

- 一个模板.

这保证了任何未命名的命名空间都具有内部链接.

普通命名空间中的匿名命名空间怎么样?它仍然保证内部联系吗?

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


将函数或变量放在匿名命名空间中会使其内部链接,即与在文件级别上声明静态但是惯用的C++相同.

在C++ 11中,static在此上下文中的使用尚未得到证实 ; 虽然未命名的命名空间是一个更好的替代方案static,但是有一些情况会失败并且可以通过以下方式解决static.inline namespace在C++ 11中引入以解决这个问题.


Chu*_*dad 5

$ 3.5/3 - "具有命名空间范围(3.3.6)的名称具有内部链接(如果它的名称)

- 显式声明为static的变量,函数或函数模板; 要么,

- 一个显式声明为const的变量,既未显式声明为extern,也未声明为具有外部链接; 要么

- 匿名联盟的数据成员.

所以,我怀疑程序中的任何名称'func3'和'func4'是否都有内部链接.他们有外部联系.但是,只是根据詹姆斯的引用,他们不能从其他翻译单位转介.