namespace N { int i; } using namespace N; using ::i; int main() {}
我用不同的编译器得到不同的结果:
> Clang(http://melpon.org/wandbox/permlink/c8vl7XbumyyS6vsw):没有错误.
> GCC(http://melpon.org/wandbox/permlink/immhNeWFCMcCA800):错误:’我’没有声明.
根据c标准,该程序是否格式良好或格式不正确?需要参考c标准.
我正在试图找出应该提交错误的编译器.
解决方法
using-directive不在全局命名空间中引入名称i,但在查找期间使用它. using-declaration使用限定查找来查找i;在使用指令的情况下进行限定查找在[3.4.3.2 p1,p2]中指定(引用来自N4527,当前的工作草案):
If the nested-name-specifier of a qualified-id nominates a namespace
(including the case where the nested-name-specifier is::
,i.e.,
nominating the global namespace),the name specified after the
nested-name-specifier is looked up in the scope of the namespace. […]For a namespace
X
and namem
,the namespace-qualified lookup set
S(X,m) is defined as follows: Let S'(X,m) be the set of all
declarations ofm
inX
and the inline namespace set ofX
(7.3.1). If
S'(X,m) is not empty,S(X,m) is S'(X,m); otherwise,m) is the
union of S(Ni,m) for all namespaces Ni nominated
by using-directives inX
and its inline namespace set.
因此,对于限定查找,第一步是查找直接在由nested-name-specifier(在本例中为::)指示的命名空间中生成的声明.没有这样的声明,因此查找然后进行到第二步,即在全局命名空间中由using-directives指定的所有命名空间中形成由限定查找找到的i的所有声明的集合.该集由N :: i组成,它是名称查找的结果,并通过using声明在全局名称空间中作为名称引入.
我发现值得注意(虽然很明显)这个限定查找的定义是递归的:在引号中使用符号,在每个命名空间中进行限定查找Ni首先会查找直接在Ni中生成的声明,然后,如果没有找到,将会接着继续查看Ni中using-directives指定的名称空间,依此类推.
对于它的价值,MSVC也接受代码.