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

2022-01-14 00:00:00 namespaces anonymous c++ linkage

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

普通命名空间中的匿名命名空间呢?它仍然保证内部链接吗?

//foo.cpp无效函数1(){//外部链接}静态无效 func2() {//内部链接}命名空间{无效 func3() {//内部链接}}命名空间 ns1 {无效 func4() {//外部链接}命名空间{无效 func3() {//还是内部链接?}}}

解决方案

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

<块引用><块引用>

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

――一个变量;或

――一个函数;或

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

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

― 属于具有链接的枚举的枚举数;或

――一个模板.

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

<块引用>

普通命名空间中的匿名命名空间呢?它仍然保证内部链接吗?

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

<小时><块引用>

将函数或变量放入匿名命名空间会使其内部链接,即.e.与在文件级别将其声明为静态相同,但符合 C++ 的习惯.

在 C++11 中,static 在这种情况下的使用是不推荐使用的;尽管 未命名命名空间是 static 的更好替代方案,但 有些情况下它会失败,可以通过 static 进行补救;inline namespace 在 C++11 中被引入来解决这个问题.

In C++, putting a function or a variable in an anonymous namespace makes its linkage internal, i. e. the same as declaring it static on a file-level, but idiomatic C++.

What about an anonymous namespace within a normal namespace? Does it still guarantee internal linkage?

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

解决方案

C++11 (draft N3337) §3.5/4: (emphasis mine)

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of

― a variable; or

― a function; or

― a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or

― a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or

― an enumerator belonging to an enumeration with linkage; or

― a template.

This guarentees that any unnamed namespace has internal linkage.

What about an anonymous namespace within a normal namespace? Does it still guarantee internal linkage?

Although within a named (normal) namespace, it's an unnamed (anonymous) namespace and thus is guaranteed to have internal linkage as per the C++11 standard.


putting a function or a variable in an anonymous namespace makes its linkage internal, i. e. the same as declaring it static on a file-level, but idiomatic C++.

In C++11 the usage of static in this context was undeprecated; although unnamed namespace is a superior alternative to static, there're instances where it fails which is remedied by static; inline namespace was introduced in C++11 to address this.

相关文章