使用“auto”的声明是否匹配使用具体types说明符的extern声明?

考虑下面的程序:

extern int x; auto x = 42; int main() { } 

铿锵3.5接受它( 现场演示 ),GCC 4.9和VS2013不( 现场演示为前者 )。 谁是对的,C ++标准中规定的正确行为在哪里?

关于这个标准,有惊人的小的。 关于所有我们听到的重新宣布是:

[C++11: 3.1/1]:声明(第7章)可能会在翻译单元中引入一个或多个名称,或者重新声明以前的声明引入的名称。 [..]

也是auto语义的唯一相关部分:

[C++11: 7.1.6.4/3]:否则,variables的types是从其初始值设定项中推导出来的。 [..]

(提醒我们x的types是int )。

我们知道一个variables必须被所有的声明赋予相同的types:

[C++11: 3.5/10]:所有types的调整(其中typedefs(7.1.3)被它们的定义replace)之后, 所有引用给定variables或函数的声明指定的types应该是相同的数组对象的声明可以指定数组types由于是否存在主数组bound(8.3.4)而不同。 对types标识违反此规则不需要诊断。

而“毕竟types的调整”应该关注auto参与的所有问题; 那么我的解释是, 这本质上是一个在inttypes的全球范围内对x的有效重新声明(和定义),并且叮当是正确的 。 即使我们build议auto不算“调整types”,因为不需要诊断,在最坏的情况下, 所有列出的实现都是按照自己的方式来执行的。

我相信海湾合作委员会和Visual Studio正在以下几点为灵感:

[C++11: 7.1.6.4/5]:在本节中未明确允许的情况下使用auto的程序是不合格的。

…但我认为这是短视的。 标准语言似乎不可能禁止通常的重新声明规则,仅仅是因为它们没有在7.1.6.4重复或明确引用。

C ++ 14增加了关于函数声明与推导types相关的措词:

[C++14: 7.1.6.4/13]:使用占位符types声明的返回types的函数或函数模板的重新声明或特化,也应该使用该占位符,而不是推导的types。 [..]

通过对称可以表明,在你的int情况下,GCC和VS在拒绝程序时是正确的。 然而,这是一个不同的特征(因为扣除不能用于单纯的声明),因此是不同的情况。

无论哪种方式,改进的标准措辞将有助于这里。 我认为这是一个相当小的编辑缺陷。