Я недавно наткнулся на эту проблему
for(int i=0,n=v.size(); i<n; i++) {
...
P2d n = ... <<<--- error here
}
компилятор жаловался на то, что локальная переменная n
уже определена, несмотря на то, что открытая скобка выглядит так, как будто она должна начать новую область.
В действительности стандарт имеет специальную формулировку для этого, и хотя код скомпилирован с g++ 4.6.3, он жалуется на более поздние версии и другие компиляторы.
Какое обоснование (если есть) за этим специальным правилом?
Чтобы быть более ясным: стандарт объясняет, что это не разрешено, и у меня нет вопросов о технической причине, для которой эта ошибка: мне просто интересно, почему комитет решил использовать специальные дополнительные правила, а не просто создание другой вложенной области при просмотре открывающей скобки (например, это происходит в других местах).
Например, чтобы закончить код, вы можете просто обернуть тело с помощью двух пар привязок вместо одного...
Также обратите внимание, что фигурные скобки после for/while/if
, хотя считается хорошей практикой, не являются обязательными, а не частью синтаксиса, но все же существует область, содержащая переменные цикла (поэтому, используя определение функции как другой пример, где область локалей является телом функции, не имеет значения: тело функции не является выражением, а фигурные скобки являются обязательными).
В синтаксисе С++ тело for
является просто выражением; однако, если это утверждение является упорядоченной группой, тогда он получает специальную обработку в for/while/if
(этого не происходит, когда вы используете командную группу как выражение в другом месте на языке).
В чем причина добавления этого дополнительного осложнения к языку? Это, по-видимому, не нужно и просто обрабатывает фигурные скобки, поскольку другой внутренний объем кажется мне проще.
Существуют ли случаи, когда этот более простой и более регулярный подход не работает?
Обратите внимание, что Я не спрашиваю мнения. Либо вы знаете, почему комитет принял это решение (требуя также довольно сложной формулировки в стандарте, вместо того, чтобы просто иметь тело в качестве регулярного заявления с регулярной обработкой блока, заключенного в фигурные скобки при использовании в качестве заявления), или вы этого не делаете.
ИЗМЕНИТЬ
"Синтаксис" для синтаксиса для меня неестественен, но технически возможен для оператора for
, который может быть рационализирован как единый блок с обратным выражением goto
, но его трудно защитить в очень схожем case для оператора 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
и часть else
оператора if
та же область? Нет, потому что вы можете объявить две переменные z
. Являются ли они отдельными областями? Нет, потому что вы не можете объявить x
.
Единственная рационализация, которую я вижу, состоит в том, что части then
и else
действительно являются отдельными областями, но с добавленным (странным) правилом, что переменная, объявленная в условии, не может быть объявлена в области. Почему это лишнее странное правило ограничения присутствует в том, о чем я прошу.