Когда я попробовал следующий код, я получил упомянутую ошибку.
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
}