namespace
n1
{
{
struct X{};
int n1_i;
int fn(){return 0;}
}
int fn(){return 0;}
}
namespace
n2
{
using namespace n1;
enum {_};
}
{
using namespace n1;
enum {_};
}
struct
X
{}
;
n1::X x;
X gx; // ::X or n1::X ?, C2872: “X” : 不明确的符号
int i = n1_i; // access n1::n1_i, OK
int i2 = fn(); // access n1::fn, OK
X gx; // ::X or n1::X ?, C2872: “X” : 不明确的符号
int i = n1_i; // access n1::n1_i, OK
int i2 = fn(); // access n1::fn, OK
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
当两个命名空间有如上形式时,第一个命名空间的符号会“泄露”到全局命名空间。泄露发生的充要条件是:n2中using了n1,并且n2中至少有一个枚举项。
这样一来n1中的符号会污染全局命名空间,从而造成无故的符号解析多义,导致C2872编译错误。
如果把n2中的enum {_};改成enum{};则不会发生符号泄露。
在VC8.0上测试没有出现问题。目前还没找到一个较理想的解决办法。
这个bug造成的问题已经影响了我们的开发进度,如果我们使用的是正版VS2003不知道是否可以就此问题起诉微软。