命名空间别名是否会改变链接?

4

据我所知,.cpp文件中的全局变量是外部链接的。假设有两个源文件:a.cppb.cpp

// a.cpp
namespace a_ns
{
  int foo;
}

// b.cpp
namespace b_ns
{
  int foo;
}

现在假设两个文件都在namespace ns=a_ns;namespace ns=b_ns;之后,这会触发任何未定义的行为吗,例如如果a.cppb.cpp只是为foo使用了相同的命名空间ns


只有具有外部链接的变量才会被外部链接。并非所有“全局变量”都需要具有外部链接。 - Kerrek SB
2个回答

5
不行。您提出的别名并不改变变量的限定名称a_ns :: foob_ns :: foo ,它们是不同的。

但是当你引用 ns::foo 会发生什么呢?(nsns_ans_b 都别名的通用命名空间别名)。 - vsoftco
@vsoftco:当你引用 ns::foo 时,你引用对应的变量——无论是 a_ns::foo 还是 b_ns::foo,具体取决于上下文。 - Kerrek SB
1
你不能同时拥有 namespace ns=a_ns;namespace ns=b_ns;。引用标准:“在一个声明区域内,可以使用命名空间别名定义来重新定义在该声明区域中声明的命名空间别名,以仅引用它已经引用的命名空间。” - Benjamin T
@KerrekSB 我认为这正是问题所在,即将具有相同名称的2个命名空间别名起来... - vsoftco

3
如果您为foo使用不同的命名空间,则会引入两个不同的变量,即a_ns::foob_ns::foo。因此,没有歧义、冲突或未定义行为-就像您调用一个foo和另一个bar一样,只是两个不同的变量。
即使在全局范围内,命名空间别名也不会与其他翻译单元产生歧义,而重复的命名空间名称会产生歧义。参见此在线c++标准草案中的命名空间别名,其中定义了程序中命名空间名称的唯一性,但仅在声明区域内定义了命名空间别名的唯一性:

7.3.2 命名空间别名

在同一声明区域中,不得将命名空间名称或命名空间别名声明为任何其他实体的名称。在全局范围内定义的命名空间名称不得在程序的任何全局范围内声明为任何其他实体的名称。...

因此,在a.cpp中引入的命名空间别名namespace ns=a_ns只能在a.cpp中“可见”,而在b.cpp中引入的namespace ns=b_ns只能在b.cpp中“可见”。因此,每个ns::foo的使用将分别明确地引用a_nsb_ns
但是,如果您实际上在两个不同的翻译单元中定义了相同的命名空间foo,例如在a.cppb.cpp中都定义了namespace ns { int foo; },则每个单独的.cpp文件将被正确编译,但您将收到一个链接器错误,例如duplicate symbol __ZN2ns3fooE in: ../a.o; ../b.o

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