C++ C+中标识符的链接+;使用说明符extern声明

C++ C+中标识符的链接+;使用说明符extern声明,c++,c++17,constants,extern,linkage,C++,C++17,Constants,Extern,Linkage,在C标准(6.2.2标识符链接)中,有足够清晰的文字 4表示使用存储类说明符extern声明的标识符 在一个范围内,该标识符的先前声明是 可见,31)如果先前的声明指定了内部或外部 链接,后面声明中标识符的链接是 与先前声明中指定的链接相同。如果事先没有 声明是可见的,或者如果先前的声明指定否 链接,则标识符具有外部链接 但是,在C++的标准中,通过第6.5节程序和链接,我找不到类似的语句。 问题是由于C++ 17标准的引用引起的。 3具有命名空间作用域(6.3.6)的名称如果是 姓名 (3.2

在C标准(6.2.2标识符链接)中,有足够清晰的文字

4表示使用存储类说明符extern声明的标识符 在一个范围内,该标识符的先前声明是 可见,31)如果先前的声明指定了内部或外部 链接,后面声明中标识符的链接是 与先前声明中指定的链接相同。如果事先没有 声明是可见的,或者如果先前的声明指定否 链接,则标识符具有外部链接

但是,在C++的标准中,通过第6.5节程序和链接,我找不到类似的语句。 问题是由于C++ 17标准

的引用引起的。 3具有命名空间作用域(6.3.6)的名称如果是 姓名

(3.2)-非易失性常量限定类型的非内联变量 既不是显式声明为extern,也不是以前声明为 有外部联系;或

现在考虑下面的声明

const int x = 100;
extern const int x;
<> P> >虽然不知道代码是不正确的还是常数<代码> x>代码>虽然它是用指定符<代码> ExtNe>代码>声明的,但它的内部链接是有关联的,或者标准在这个段落的描述中有缺陷,或者我没有在C++标准中引用类似于C标准的引用。在看了这本书之后,它说:

有关使用外部说明符声明的名称的链接,请参见[basic.link]

但是,关于使用
extern
说明符声明的规则主要在[basic.link#6]中,即:

在块作用域中声明的函数名和块作用域外部声明声明的变量名具有链接。如果将这样的声明附加到命名模块,则程序的格式不正确。如果存在具有链接的实体的可见声明,则忽略在最内层封闭命名空间范围外声明的实体,这样,如果两个声明出现在同一声明区域中,则块范围声明将是(可能格式错误的)重新声明,块范围声明声明同一实体并接收前一声明的链接。如果存在多个这样的匹配实体,则程序的格式不正确。否则,如果未找到匹配的实体,则块范围实体将接收外部链接。如果在一个翻译单元中,同一个实体同时声明了内部和外部链接,则程序的格式不正确


听起来这些规则只适用于块范围声明,而不适用于使用外部说明符声明的命名空间范围声明。除本段外,[basic.link]节中没有其他规则表明
extern
说明符声明的名称链接是什么。与C标准中所说的不同,这些规则适用于使用
extern
说明符声明的任何声明(无论声明声明的作用域是什么类型)。

如果您查看第10.1.1节存储类说明符,第6段,有几个示例。没有一个匹配您的案例,但是有一个
静态int b;//b具有内部链接
外部链接b;//b仍然有内部链接
一个很接近。@1201程序示例不是描述。:)除了示例之外,必须有一个说明说明这些示例是有效的。哇。我没有意识到这一微妙之处(即,我总是“直觉地”使用的顺序有那么重要)。我做了一个例子来说明这一点。好吧,确实包含了一个规范性的句子,说链接必须一致。@cplearner再次引用没有说在后一个声明中使用指定符extern。它假设这已经被描述过了,实际上是/3和/4相关,尽管它们很少提到
extern
。很多手工操作都是围绕着像“上面”这样的词进行的。@DavisHerring在我看来,这并不明显。我认为应该在[dcl.stc]中添加一些东西,特别说明
extern
说明符是什么能力(例如,
extern
指定的变量如何链接一个有链接的变量)很难平衡非冗余性和可访问性,我们有时不得不求助于“标准不是教程”。[basic.link]当然需要澄清,但要知道,
extern
从来不会真正影响链接;它将其应用于局部变量,但在其他情况下,它只会阻止声明成为定义(这就是为什么它对函数没有任何意义)。外部链接只是默认设置(在C++20使其有时成为模块链接之前)。@DavisHerring然而,当前的标准不足以说明哪个实体将链接到由
extern
指定的变量。
basic.link#6
只说明了块作用域变量,而不是具有命名空间作用域的变量(由
extern
指定)。即使是
P1787
,它只是删除了整个basic.link#6,并没有给出新的措辞。P1787的[basic.link]/9非常清楚地说明了哪些声明集声明了相同的实体。只是,在函数之外,
extern
根本不会影响该确定,除非禁用常量变量上的(历史)隐式
static