Когда я попробовал следующий код, я получил упомянутую ошибку.
if(a==1)
int b =10;
Но синтаксически корректно следующее:
if(a==1)
{
int b = 10;
}
Почему это?
Когда я попробовал следующий код, я получил упомянутую ошибку.
if(a==1)
int b =10;
Но синтаксически корректно следующее:
if(a==1)
{
int b = 10;
}
Почему это?
На самом деле это довольно интересный вопрос. Это не так просто, как кажется. Для справки, я собираюсь основывать это на последней грамматике языка C11, определенной в N1570
Я думаю, что контринтуитивная часть вопроса: если это правильно C:
if (a == 1) {
int b = 10;
}
то почему это не так правильно??
if (a == 1)
int b = 10;
Я имею в виду, что однострочный условный оператор if
должен быть точным либо с фигурными скобками, либо без них, правильно?
Ответ лежит в грамматике оператора if
, как это определено стандартом C. Соответствующие части грамматики, приведенные ниже. Вкратце: строка int b = 10
- это декларация, а не инструкция, а для грамматики для оператора if
требуется утверждение после условного тестирования. Но если вы вложите объявление в фигурные скобки, оно станет утверждением и всем хорошо.
И только для того, чтобы полностью ответить на вопрос - это не имеет никакого отношения к сфере применения. Переменная b
, которая существует внутри этой области действия, будет недоступна извне, но программа по-прежнему синтаксически корректна. Строго говоря, компилятор не должен выставлять на него ошибку. Конечно, вы должны строить с -Wall -Werror
в любом случае; -)
(6.7) declaration: declaration-specifiers init-declarator-listopt; static_assert-declaration (6.7) init-declarator-list: init-declarator init-declarator-list , init-declarator (6.7) init-declarator: declarator declarator = initializer (6.8) statement: labeled-statement compound-statement expression-statement selection-statement iteration-statement jump-statement (6.8.2) compound-statement: { block-item-listopt} (6.8.4) selection-statement: if ( expression ) statement if ( expression ) statement else statement switch ( expression ) statement
{ }
→
определяет область действия, поэтому if(a==1) { int b = 10; }
говорит, что вы определяете int b, для {} - этой области. Для
if(a==1)
int b =10;
нет области. И вы не сможете использовать b
где угодно.
В C89 переменная может быть определена только в верхней части блока.
if (a == 1)
int b = 10; // it just a statement, syntacitially error
if (a == 1)
{ // refer to the beginning of a local block
int b = 10; // at the top of the local block, syntacitially correct
} // refer to the end of a local block
if (a == 1)
{
func();
int b = 10; // not at the top of the local block, syntacitially error, I guess
}