Объявление переменной после метки 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, я считаю, что область не является вопрос здесь. Но тогда, почему я получаю эту ошибку?
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