2010-11-15 81 views
14

在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? 
     } 
    } 
} 
+1

错误的假设。 anonyomus命名空间中的变量具有外部链接,除非声明为'static'。 – MSalters 2010-11-15 10:12:13

+1

@ MSalters:我认为用C++ 11这已经改变了。 §3.5/ 4:在未命名名称空间内直接或间接声明的未命名名称空间或名称空间具有内部链接。所有其他名称空间都有外部链接.' – legends2k 2013-10-21 18:09:51

+1

@ legends2k:这是另一个更改的一部分,它使这些名称作为模板参数有效(在C++ 03中,模板参数需要外部链接,这是由匿名名称空间中定义的常量满足的) – MSalters 2013-10-21 18:37:04

回答

11

C++ 11(N3337草案)§3.5/ 4:(重点煤矿)

具名命名空间或具名命名空间内直接或间接地声明命名空间具有内部连接。所有其他名称空间都有外部链接。以上尚未给定的内部键的具有名称命名空间范围具有相同的连锁作为封闭命名空间,如果它是

名称 - 的变量;或

- 一个函数;或

- 一命名的类(第9节),或者在一个typedef声明,其中所述类具有用于连杆机构的目的typedef名称(7.1.3)所定义的未命名的类;或

- 一个名为枚举(7。2)或在typedef声明中定义的未命名枚举,其中枚举具有用于链接目的的typedef名称(7.1.3);或

- 枚举器属于枚举与链接;或

- 模板。

这guarentees任何具名命名空间有内在联系。

那么正常名称空间内的匿名命名空间呢?它仍然保证内部联系?

虽然名为(正常)名称空间中,这是一个未命名的(匿名)的命名空间,从而保证具有内部链接具体根据C++ 11标准。


把一个函数或变量以匿名的命名空间使得其联动内部,也就是即就像在文件级声明静态C++一样。

在C++ 11的static在此上下文中的使用是undeprecated;虽然unnamed namespace is a superior alternative to staticthere're instances where it fails这是由static纠正; inline namespace was introduced in C++11来解决这个问题。

15

这并不一定是在一个匿名的命名空间的实体有内部链接的情况;他们实际上可能有外部联系。

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

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

虽然具名命名空间的实体可能有外部链接,它们是有效地独有的翻译单元的名称资格因此无法从任何其他翻译单位看到。

+2

快速跟进:您知道内部链接是否有助于编译器为其优化做出更好的代码转换决策,还是不是问题? – 2010-11-15 03:06:27

+0

@亚历乙B:这是一个很好的问题。我的猜测是,如果编译器或链接器可以对具有内部链接的实体执行优化,则它们可以对未命名的名称空间中的实体执行相同的优化。虽然我不能肯定地说。其他人会比我知道得多。 – 2010-11-15 03:11:04

5

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

名称

内部连接 ​​- 一个变量, 即 功能或功能模板显式声明静态的;或者,

- 这是显式声明 常量既不明确宣布 的extern也没有先前声明有01 变量外部联动;或

- 一个数据成员匿名联合的 。

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