未命名的命名空间对全局变量有什么影响?

26
这两者之间有什么不同?
cpp 文件:
namespace
{
    int var;
}
或者
int var;

如果两者都放在cpp文件中,是否正确将变量放在匿名命名空间中,以使其仅对该文件私有?但是,如果我们将全局变量放在cpp文件中,那么该变量不也是私有的,因为您永远不会包含.cpp文件吗?

5个回答

32
在第二种情况下,如果您不使用匿名命名空间,如果任何其他cpp文件声明了extern int var;,它将能够使用您的变量。
如果您使用匿名命名空间,则在链接时,其他cpp文件将生成未定义引用错误。

2
所以我认为通过将变量设置为静态,您可以获得相同的结果。 - Dacav
通过将其定义为const,也可以在C++中实现True,这将意味着静态。 - Didier Trosset
1
@Dacav:没错。但是C++的做法是使用匿名命名空间。使用static只是因为C++需要向后兼容C语言。 - Martin York
2
静态工作,但已被弃用,因为它仅适用于变量。匿名命名空间可以包含其他内容,例如类定义。 - Jon Reid
@Jon Reid:说得好。然而,如果你将一个类声明到 .cpp 文件中,那么没有人会在其命名空间中拥有它。相反,如果你将匿名命名空间放入 .h 文件中,当你包含头文件时就无法操作其中的任何内容。声明一个类不会向你的目标文件添加符号,而变量和函数会这样做。 - Dacav

4
在第二种情况下,其他.cpp文件可以这样访问变量:
extern int var;
var = 42;

链接器将会找到它。在第一种情况下,变量名已经被混淆了,无法理解 :) 因此上述操作是不可能的。


3
第二个版本在全局命名空间中定义 -- 其他.cpp文件可以通过声明 extern int var; 来访问它,即使他们不这样做,如果其他人在全局命名空间中使用相同的名称,你将会得到一个链接错误(多次定义的符号)。

2
除了 Nikolai 和其他人提到的原因外,如果您不使用匿名命名空间,可能会与其他全局数据发生名称冲突。如果您使用匿名命名空间,则将代替全局数据。
来自 cprogramming.com:“在命名空间内部,您可以确保没有全局名称冲突,因为每个命名空间的函数名称优先于外部函数名称。”

1

两点需要注意:

  1. 如果 extern int var; 变量没有在未命名的命名空间中,任何人都可以访问它。
  2. 如果在另一个文件中有另一个全局变量 int var,则会出现此变量的多个定义。

根据规范:

在翻译单元中所有唯一的出现都将被替换为相同的标识符,并且该标识符与整个程序中的所有其他标识符都不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接