namespace N { extern int j; int j; } int main() { extern int w; int w; }
这些段落介绍了在块范围内使用extern声明的一些内容,但是似乎没有证明错误信息的正当性:
§3.3.1/ 4
Given a set of declarations in a single declarative region,…
[ Note: These restrictions apply to the declarative region into which
a name is introduced,which is not necessarily the same as the region
in which the declaration occurs. In particular,
elaborated-type-specifiers (7.1.6.3) and friend declarations (11.3)
may introduce a (possibly not visible) name into an enclosing
namespace; these restrictions apply to that region. Local extern
declarations (3.5) may introduce a name into the declarative region
where the declaration appears and also introduce a (possibly not
visible) name into an enclosing namespace; these restrictions apply to
both regions. —end note ]
§3.3.2/ 10
[ Note: Friend declarations refer to functions or classes that are
members of the nearest enclosing namespace,but they do not introduce
new names into that namespace (7.3.1.2). Function declarations at
block scope and variable declarations with the extern specifier at
block scope refer to declarations that are members of an enclosing
namespace,but they do not introduce new names into that scope. —end
note ]
解决方法
尤其是:
The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type,ignoring entities declared outside the innermost enclosing namespace scope,the block scope declaration declares that same entity and receives the linkage of the prevIoUs declaration. If there is more than one such matching entity,the program is ill-formed. Otherwise,if no matching entity is found,the block scope entity
receives external linkage.
所以,extern int w声明具有链接的w(外部链接,在这种情况下,因为在该点没有匹配的实体可见).
然后,您尝试定义一个没有链接的本地w(通过§3.5/ 8).
这在同一范围内给出了相同名称的两个声明,但具有不同的联系. §3.3.1/ 4禁止:
Given a set of declarations in a single declarative region,each of which specifies the same unqualified name,
- they shall all refer to the same entity,or all refer to functions and function templates; or
- exactly one declaration shall declare a class name or enumeration name that is not a typedef name
and the other declarations shall all refer to the same variable or enumerator,or all refer to functions and function templates; in this case the class name or enumeration name is hidden (3.3.10).
既不涉及函数,函数模板,类名称或枚举名称,因此这些“escape子句”都不适用.这两个声明必须引用同一个实体,它必须具有外部链接和无连接.由于这是不可能的,代码是不正确的.