Rozważ ten kod:
void foo()
{
goto bar;
int x = 0;
bar: ;
}
GCC i Clang odrzucają to , ponieważ przejście do bar:
obejścia inicjalizacji zmiennej. MSVC nie narzekają na wszystko (z wyjątkiem stosowania x
po bar:
powoduje ostrzeżenie).
Możemy zrobić podobnie z switch
:
void foo()
{
switch (0)
{
int x = 0;
case 0: ;
}
}
Teraz wszystkie trzy kompilatory emitują błędy .
Czy te fragmenty są źle sformułowane? A może powodują UB?
Kiedyś myślałem, że oba są źle sformułowane, ale nie mogę znaleźć rewelacyjnych części standardu. [stmt.goto] nic o tym nie mówi, podobnie jak [stmt.select] .
c++
language-lawyer
goto
initializer
variable-declaration
HolyBlackCat
źródło
źródło
x
po skoku./permissive-
flagę do MSVC, a ona również narzeka. Nie wiem jednak, czy zachowanie MSVC bez tej flagi jest dobrze zdefiniowane (zakładam, że tak, w przeciwnym razie dlaczego mieliby na to pozwolić?).Odpowiedzi:
Jest źle sformułowany, gdy inicjalizacja nie jest pusta.
Inicjator sprawia, że inicjalizacja nie jest pusta. Dla kontrastu to
byłby dobrze uformowany. Miałyby jednak zastosowanie zwykłe zastrzeżenia dotyczące używania
x
z nieokreśloną wartością.źródło
Z oświadczenia goto :
źródło