Объявление переменной после метки goto



сегодня я нашел одну интересную вещь. Я не знал, что нельзя объявить переменную после метки goto.



компиляция следующего кода



#include <stdio.h>
int main() {
int x = 5;
goto JUMP;
printf("x is : %dn",x);
JUMP:
int a = 0; <=== giving me all sorts of error..
printf("%d",a);
}


выдает ошибки типа



temp.c: In function ‘main’:
temp.c:7: error: expected expression before ‘int’
temp.c:8: error: ‘a’ undeclared (first use in this function)
temp.c:8: error: (Each undeclared identifier is reported only once
temp.c:8: error: for each function it appears in.)


теперь какова логика за этим? Я слышал, что нельзя создавать переменные внутри операторов case switch. Поскольку JUMP находится внутри той же области (область основной функции, в моем случае) оператора goto, я считаю, что область не является вопрос здесь. Но тогда, почему я получаю эту ошибку?

525   8  

8 ответов:

синтаксис просто не позволяет этого. §6.8.1 Обозначены Высказывания:

labeled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement

обратите внимание, что нет никакого предложения, которое допускает "помеченное объявление". Это просто не часть языка.

Вы можете легко обойти это, конечно, с пустым заявлением.

JUMP:;
int a = 0;

вы хотите точку с запятой после метки, как это:

 #include <stdio.h>
 int main() {
     int x = 5;
     goto JUMP;
     printf("x is : %d\n",x);
 JUMP: ;     /// semicolon for empty statement
     int a = 0; 
     printf("%d",a);
 }    

тогда ваш код компилируется правильно для стандарта C99, с gcc -Wall -std=c99 -c krishna.c (Я использую GCC 4.6 на Debian/Sid/AMD64).

моя версия gcc (4.4) дает эту ошибку компиляции:

t.c:7: error: a label can only be part of a statement and a declaration is not a statement

. Это сообщение об ошибке говорит все это.

простое объяснение, отличное от спецификации, заключается в том, что компилятор exepecting код после goto, чтобы быть чем-то, что компилируется в операцию, которую он может затем вычислить смещение, и пинает, потому что ваше объявление переменной не является оператором/блоком, который он может скомпилировать в такое смещение.

Ну, во-первых, вы должны быть последовательны. Это либо LABEL или label. Во-вторых, label является частью инструкции, и объявление недостаточно отвечает описанию.

вы можете заменить LABEL: С label: ; и тогда это, скорее всего, для компиляции.

EDIT: теперь, когда вы отредактировали свой код на всем протяжении, он должен быть JUMP: заменить JUMP: ; ; -)

Если вы знаете, почему вы не можете создавать переменные внутри оператора case switch, в основном это та же причина, по которой вы не можете этого сделать. В качестве исправления, вы можете попробовать это,

#include <stdio.h>
int main() {
    int x = 5;
    goto JUMP;
    printf("x is : %d\n",x);
JUMP:
    {                                              //Note this
       int a = 0;  // <=== no more error..
       printf("%d",a);
    }                                             //Note this
}

Это не из-за метки как таковой, это потому, что уже есть операторы (goto и printf). Последний стандарт, по-видимому, допускает объявления переменных в произвольных местах, но не каждый компилятор полностью соответствует стандарту. Кроме того, идентификаторы чувствительны к регистру в C, и ваша метка должна быть одинаковой в обоих местах.

#include <stdio.h>
int main() {
    int x = 5;
    goto JUMP;
    printf("x is : %d\n",x);
JUMP:
    printf("Do anything after label but dont declare 
    anything. even empty statement will also work 
    because label can only be part of a statement");
    int a = 0;  
    printf("%d",a);
}

Comments

    Ничего не найдено.