Подтвердить что ты не робот

Ошибка C: ожидаемое выражение перед int

Когда я попробовал следующий код, я получил упомянутую ошибку.

if(a==1)
  int b =10;

Но синтаксически корректно следующее:

if(a==1)
{
   int b = 10;
}

Почему это?

4b9b3361

Ответ 1

На самом деле это довольно интересный вопрос. Это не так просто, как кажется. Для справки, я собираюсь основывать это на последней грамматике языка 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

Ответ 2

{ }

определяет область действия, поэтому if(a==1) { int b = 10; } говорит, что вы определяете int b, для {} - этой области. Для

if(a==1)
  int b =10;

нет области. И вы не сможете использовать b где угодно.

Ответ 3

В 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
}