Объявление переменной после метки goto
Сегодня я нашел одну интересную вещь. Я не знал, что нельзя объявлять переменную после метки goto.
Компиляция следующего кода
#include <stdio.h>
int main() {
int x = 5;
goto JUMP;
printf("x is : %d\n",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, я считаю, что область не является проблемой здесь. Но почему, почему я получаю эту ошибку?
Ответы
Ответ 1
Синтаксис просто не позволяет этого. §6.8.1 Обозначенные метки:
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
Обратите внимание, что нет предложения, которое допускает "помеченную декларацию". Он просто не является частью языка.
Вы можете тривиально обойти это, конечно, с пустой инструкцией.
JUMP:;
int a = 0;
Ответ 2
Вы хотите, чтобы точка с запятой после метки выглядела следующим образом:
#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).
Ответ 3
Моя версия gcc (4.4) дает эту ошибку компиляции:
t.c:7: error: a label can only be part of a statement and a declaration is not a statement
. Это сообщение об ошибке сообщает все.
Ответ 4
Простое объяснение, отличное от спецификации, говорит, что компилятор не выполняет код после того, как goto является компилятором в операцию, которая затем может вычислять смещение, и пинает, потому что объявление переменной isn ' t оператор/блок, который он может скомпилировать в такое смещение.
Ответ 5
Хорошо, сначала вы должны быть последовательными. Это либо LABEL
, либо LABEL
. Во-вторых, метка является частью инструкции, и декларация не соответствует описанию.
Вы можете заменить LABEL:
на label: ;
, а затем его можно скомпилировать.
РЕДАКТИРОВАТЬ: Теперь, когда вы отредактировали код целиком, он должен быть JUMP:
заменен на JUMP: ;
; -)
Ответ 6
Если вы знаете, почему вы не можете создавать переменные внутри case-кода коммутатора, в основном это та же причина, почему вы тоже не можете это сделать. В качестве исправления вы можете попробовать это,
#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
}
Ответ 7
Это не из-за ярлыка как такового, потому что уже есть инструкции (goto и printf). Последний стандарт, по-видимому, допускает объявления переменных в произвольных местах, но не каждый компилятор полностью соответствует стандарту. Кроме того, идентификаторы чувствительны к регистру в C, и ваша метка должна быть одинаковой в обоих местах.
Ответ 8
#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);
}