Ошибка времени компиляции при объявлении переменных в C внутри секции управления

Я пытаюсь скомпилировать программу (Листинг 12.13 - manydice.c из C Primer Plus 6-го издания Стивена Прата), но получаю ошибку компиляции: "статус" не объявлен (первое использование в этой функции).

Буду признателен также за разъяснения о стандарте c99 "декларирование в любом месте".

Вот часть кода:

int main(void)
{
    int dice, roll;
    int sides;

    srand((unsigned int) time(0));       /* randomize seed       */
    printf("Enter the number of sides per die, 0 to stop.\n");
    while(scanf("%d", &sides) == 1 && sides > 0)
    {
        printf("How many dice?\n");
        if((status = scanf("%d", &dice)) != 1)
        {
            if(status == EOF)
            {
                break;                  /* exit loop            */
            }
            ...

Сообщение об ошибке:

||=== Build: Debug in dice (compiler: GNU GCC Compiler) ===|
~manydice.c||In function 'main':|
~manydice.c|19|error: 'status' undeclared (first use in this function)|
~manydice.c|19|note: each undeclared identifier is reported only once for each function it appears in|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Опции: (При использовании code::blocks 16.01 в версии mingw 32bit - gcc отображается gcc 4.9.2, 32-разрядная версия Windows 7 Ultimate)

 mingw32-gcc.exe -Wall -g -std=c99  -c

Почему я получаю эту ошибку?

2 ответа

Решение

Во-первых, вы утверждаете, что объявления переменных разрешены в "контрольных разделах" C, среди которых вы, очевидно, включаете условие if заявление. Вы ошибаетесь. Начиная с C99, объявление разрешено вместо первого выражения в управляющем предложении for цикл, но не вместо управляющих выражений в других структурах управления потоком, таких как if или же while заявления.

Во-вторых, "объявление" не является синонимом "первого появления". Объявление идентификатора связывает по крайней мере информацию о типе с этим идентификатором, и его размещение определяет область действия идентификатора. Если нет декларации - как в вашем случае - тогда нет области действия, в которой может использоваться идентификатор. Изначально C имел более слабые правила в этом отношении, но, поскольку вы, кажется, хотите полагаться на C99, они не имеют значения.

Самое простое объявление для вашей переменной status будет это:

int status;

Это должно появиться перед первым использованием этой переменной, и ее область действия распространяется до конца самого внутреннего включающего блока или до конца файла, если он появляется вне какого-либо блока. В вашем случае, однако, я бы просто заменил

        if((status = scanf("%d", &dice)) != 1)

с

         int status = scanf("%d", &dice);

         if (status != 1)

Что оба заявляют status и вычисляет начальное значение для него, которое вы затем используете. Я нахожу это более понятным, чем выполнение вычисления значения и проверки в одном выражении.

Ваше ожидание (или понимание) неверно.

Цитирование главы §6.8.4.1, C11синтаксис для if заявление

if ( выражение ) заявление

и объявление переменной не является выражением выражения.

Однако вы можете иметь переменную, определенную в части инструкции.

Другие вопросы по тегам