为什么两个不同的未命名名称空间可以共存于一个cpp文件中

Why could two different unnamed namespace co-exist in one cpp file?

本文关键字:空间 于一个 文件 cpp 两个 未命名 为什么      更新时间:2023-10-16

据说翻译单元中只有一个唯一的未命名名称。然而,吼叫的台词仍然在编。

//test.cpp
namespace xxx{
namespace {
int x = 0;
}
}
namespace yyy{
namespace {
int x = 0;
}
}

我猜测嵌套的未命名命名空间中的代码就像父命名空间中的编码一样,而嵌套的未名称命名空间毫无意义。不知道对不对。

未命名的命名空间在其作用域中是唯一的。例如

namespace named {
namespace {
int x = 0;
}
namespace {
int x = 0;
}
}

将导致错误。这同样适用于全球范围。

在您提供的案例中,xxxyyy中的未命名命名空间对于它们各自的作用域是唯一的,因此不存在名称冲突。

匿名命名空间的规则与您期望的不同
根据C++标准/[名称空间.未命名]:

未命名的命名空间定义的行为就像被取代一样

inline namespace unique { /* empty body */ } 
using namespace unique ;
namespace unique { namespace-body }

其中inline出现当且仅当它出现在未命名的命名空间定义和中所有出现的unique翻译单元替换为相同的标识符,并且标识符不同于翻译单元中的所有其他标识符。

因此,您的代码是有效的,因为您每次都在不同封闭命名空间的嵌套匿名命名空间中定义x(如果uuuu是标准中提到的假设唯一标识符,则它将是xxx::uuuuyyy::uuuu(。

重要备注:每个匿名命名空间的行为就像它们拥有相同的标识符一样,每个编译单元都是唯一的,这一事实允许继续嵌套的命名空间:

namespace xxx {
namespace {
int x = 20;
}
}
namespace test {
int x=30;     // no problem: it's a different namespace
}
namespace xxx {
namespace {
// int x;     --> forbiden because it's the same nested anonyous space than above  
int y = x;    // refers to the already defined xxx::{anonymous}::x
}
}
int main() {
cout << xxx::y<<endl;    // output is 20 and xxx::y is inaccessible from other compilation units
return 0;
}