嵌套在常规命名空间中的未命名命名空间中的实体是否具有内部链接?

问题描述 投票:0回答:3

在 C++ 中,将函数或变量放在未命名的命名空间中会使其链接成为内部链接,即。 e.与在文件级别声明它

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?
        }
    }
}
c++ namespaces language-lawyer linkage unnamed-namespace
3个回答
15
投票

C++11(草案 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
 进行补救; C++11
中引入了
inline namespace
来解决这个问题。


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

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

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

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


5
投票
$3.5/3 - “具有命名空间的名称 范围(3.3.6)具有内部链接,如果 这是

的名字

— 一个变量, 函数或函数模板是 显式声明为静态;或者,

—一个 显式声明的变量 const 并且没有明确声明 外部或之前声明有 外部链接;或

— 数据成员 一个匿名工会的成员。

所以,我怀疑程序中的任何名称“func3”和“func4”是否具有内部链接。他们有外部联系。不过,只是不能按照 James 的引述从其他翻译单位引用而已。

© www.soinside.com 2019 - 2024. All rights reserved.