16

在 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?
        }
    }
}
4

3 回答 3

15

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

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

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

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

于 2010-11-15T02:57:34.327 回答
13

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 中引入来解决这个问题。

于 2013-10-21T18:20:41.470 回答
5

$3.5/3 - “具有命名空间范围 (3.3.6) 的名称如果是

— 显式声明为静态的变量、函数或函数模板;或者,

— 显式声明为 const 且既未显式声明 extern 也未先前声明具有外部链接的变量;或者

— 匿名工会的数据成员。

因此,我怀疑您的程序中的任何名称“func3”和“func4”是否有内部链接。他们有外部联系。但是,只是不能按照詹姆斯的引用从其他翻译单位引用它们。

于 2010-11-15T03:13:06.717 回答