c – 在块范围内使用extern

clang,gcc和VS2013都抱怨在main()中重新定义w,但是我在标准中找不到不允许的东西.
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 ]

解决方法

我相信这主要是由§3.5/ 6.

尤其是:

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子句”都不适用.这两个声明必须引用同一个实体,它必须具有外部链接和无连接.由于这是不可能的,代码是不正确的.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...