问题描述
考虑以下程序:
extern int x;自动 x = 42;int main() { }
Clang 3.5 接受(现场演示),GCC 4.9 和 VS2013 不接受(前者的现场演示).谁是对的,C++ 标准中规定的正确行为在哪里?
令人惊讶的是,标准中几乎没有这方面的内容.我们听到的关于重新申报的所有信息是:
[C++11: 3.1/1]:
声明(第 7 条)可以将一个或多个名称引入翻译单元或重新声明由先前声明引入的名称.[..]
以及auto
语义的唯一相关部分:
[C++11: 7.1.6.4/3]:
否则,从其初始值设定项推导出变量的类型.[..]
(提醒我们x
的类型是int
).
我们知道变量必须被所有声明赋予相同的类型:
[C++11: 3.5/10]:
所有类型调整后(在此期间typedefs(7.1.3)被其定义替换),所有指定的类型引用给定变量或函数的声明应该是相同的,除了数组对象的声明可以指定不同的数组类型,因为存在或不存在主数组边界(8.3.4).违反此类型标识规则不需要诊断.
和类型的所有调整后"应该处理有关 我相信 GCC 和 Visual Studio 的灵感来自以下几点: …但我认为这是短视的.标准语言似乎不太可能禁止通常的重新声明规则,仅仅因为它们没有在 C++14 添加了与具有推导类型的函数声明相关的措辞: 根据对称性,人们可能会认为,在您的 无论如何,改进的标准措辞在这里都会有所帮助.我认为这是一个[相当轻微的]编辑缺陷. Consider the following program: Clang 3.5 accepts it (live demo), GCC 4.9 and VS2013 do not (live demo for the former). Who is right, and where is the correct behavior specified in the C++ Standard? There's surprisingly little in the standard about this. About all we hear about redeclaration is: and the only relevant part of (reminding us that the type of We know that a variable must be given the same type by all declarations: and the "after all adjustments of types" ought to take care of any questions regarding I believe GCC and Visual Studio are taking the following as inspiration: …but I think that this is short-sighted. It seems unlikely that the standard language is intended to prohibit the usual redeclaration rules, just because they are not repeated or explicitly referenced from within C++14 adds wording that relates to declarations of functions with deduced types: By symmetry one might suggest that, in your Either way, improved standard wording would help here. I consider it a [reasonably minor] editorial defect. 这篇关于是否使用“auto"进行声明?匹配使用具体类型说明符的 extern 声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!auto
参与所有这些的任何问题;那么,我的解释是这本质上是 x
在全局范围内的有效重新声明(和定义),类型为 int
,并且 Clang 是正确的强>.即使我们建议 auto
不算作类型调整",因为不需要诊断,最坏的情况是所有列出的实现都以自己的方式兼容.>[C++11: 7.1.6.4/5]:
在本节未明确允许的上下文中使用 auto
的程序是格式错误的.7.1.6.4
中重复或明确引用.[C++14: 7.1.6.4/13]:
使用占位符类型声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推断类型.[..]int
情况下,GCC 和 VS 拒绝该程序是正确的.然而,这是一个不同的特性(因为推导不能应用于仅仅声明),因此是一个不同的场景.extern int x;
auto x = 42;
int main() { }
auto
's semantics:x
is int
).auto
's participation in all of this; my interpretation, then, is that this is inherently a valid redeclaration (and definition) of the x
at global scope with type int
, and that Clang is correct. Even if we propose that auto
does not count as "adjustment of type", since no diagnostic is required, at worst all listed implementations are compliant in their own way.7.1.6.4
.int
case, it is intended that GCC and VS be correct in rejecting the program. However, this is a different feature (since deduction cannot be applied to mere declarations) and thus a different scenario.