【发布时间】:2014-10-15 08:11:44
【问题描述】:
我最近遇到了这个问题
for(int i=0,n=v.size(); i<n; i++) {
...
P2d n = ... <<<--- error here
}
编译器抱怨 n 局部变量已被定义,尽管左大括号看起来应该开始一个新的范围。
事实上,该标准对此有一个特殊的措辞,虽然使用 g++4.6.3 编译的代码很好,但它与更新的版本和其他编译器相冲突。
这个特殊规则背后的基本原理是什么(如果有的话)?
更清楚地说:标准说明这是不允许的,我对错误的技术原因没有任何疑问:我只是想知道为什么委员会决定使用特殊的额外规则,而不是在看到左大括号时创建另一个嵌套范围(就像在其他地方发生的那样)。
例如,为了使代码合法,您可以用 两个 大括号对而不是一个...
还请注意,for/while/if 之后的大括号虽然被认为是一种很好的做法,但 不是强制性的,也不是语法的一部分,但仍然存在包含循环变量的范围(因此使用函数定义作为另一个本地变量的范围是函数体的例子是不相关的:函数体不是语句,大括号是强制性的)。
在 C++ 语法中,for 的主体只是一个语句;但是,如果该语句恰好是一个花括号组,那么它会在 for/while/if 中得到特殊处理(当您在语言的其他地方使用花括号组作为语句时不会发生这种情况)。
在语言中添加这种额外的复杂性的原因是什么?显然不需要,只是将大括号视为另一个内部范围似乎(对我来说)更简单。
是否存在这种更简单、更常规的方法不起作用的用例?
请注意,我不是在征求意见。要么你知道委员会为什么做出这个决定(在标准中还需要一个非常详尽的措辞,而不是仅仅将正文作为常规语句,并在用作语句时定期处理大括号括起来的块),或者你不知道。
编辑
语法的“单一范围”视图对我来说是不自然的,但对于 for 语句在技术上是可行的,可以通过向后的 goto 语句将其合理化为单个块,但很难在非常相似的情况下进行辩护if 语句的情况:
if (int x = whatever()) {
int x = 3; // Illegal
} else {
int x = 4; // Illegal here too
}
但这是合法的
if (int x = whatever()) {
int z = foo();
} else {
int z = bar();
}
那么条件、then 部分和if 语句的else 部分是否相同范围?不,因为您可以声明两个 z 变量。它们是单独的范围吗?不,因为你不能声明x。
我能看到的唯一合理化是 then 和 else 部分确实是单独的范围,但是添加了(奇怪的)规则,即条件中声明的变量不能在范围中声明。为什么会出现这个奇怪的限制规则是我要问的。
【问题讨论】:
-
你基本上是在问“为什么这里没有两个嵌套范围?”
-
我很想知道实际阅读问题的人发布了多少答案(因为您清楚地承认您知道它不起作用,请注意相关标准内容等)。
-
@OliverCharlesworth:你已经有了一个范围(例如,你可以放置一个不带大括号的语句)。问题是为什么不通过创建新范围而不是添加特殊规则来正常处理大括号...
-
@DavidHeffernan:将正文视为语言中的任何其他语句有什么混乱(即,如果它是一个花括号组,则开始一个嵌套范围)?
-
我添加了 C 标签。没有多少问题值得同时使用 C 和 C++ 标记,但在这里似乎是合适的。 @OliverCharlesworth 的“因为 C 这么说”的回答自然会引出 C 为什么这么说的问题。
标签: c++