使用"auto"的声明是否匹配使用具体类型说明符的extern声明?

And*_*owl 56 c++ extern language-lawyer auto

考虑以下程序:

extern int x;
auto x = 42;
int main() { }
Run Code Online (Sandbox Code Playgroud)

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

Lig*_*ica 25

关于这一点,标准中的惊人之处很少.关于重新声明的所有内容是:

[C++11: 3.1/1]:声明(第7条)可以将一个或多个名称引入翻译单元或重新声明先前声明引入的名称.[..]

auto语义的唯一相关部分:

[C++11: 7.1.6.4/3]:否则,从其初始化程序推导出变量的类型.[..]

(提醒我们的类型xint).

我们知道所有声明都必须为变量赋予相同的类型:

[C++11: 3.5/10]:在对类型进行所有调整之后(其中typedefs(7.1.3)被其定义替换),引用给定变量或函数的所有声明指定的类型应该是相同的,除了数组对象的声明可以指定数组类型是否存在主阵列界限(8.3.4).违反此规则的类型标识不需要诊断.

而"所有类型调整后"应该处理有关auto参与所有这些问题的任何问题; 因此,我的解释是,这本质上是对x具有类型的全局范围的有效重新声明(和定义)int,并且Clang是正确的.即使我们建议auto不计入"类型调整",因为不需要诊断,最坏的情况是所有列出的实现都以它们自己的方式兼容.

我相信GCC和Visual Studio正在以下列为灵感:

[C++11: 7.1.6.4/5]:auto在本节未明确允许的上下文中使用的程序格式不正确.

......但我认为这是短视的.标准语言似乎不太可能禁止通常的重新声明规则,只是因为它们不会从内部重复或明确引用7.1.6.4.

C++ 14添加了与推导类型的函数声明相关的措辞:

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

通过对称,人们可能会建议,在您的int情况下,GCC和VS在拒绝程序时是正确的.但是,这是一个不同的特征(因为演绎不能仅用于声明),因此是一个不同的场景.

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

  • 我有点困惑,但有一件事我肯定会同意:改进措辞会有很大帮助. (2认同)