Sono in vena di spiegare questo senza Memory cruento la i vostri dettagli (credetemi, ottengono molto in cui i VLA sono usati; vedere @ la risposta di Ulfalizer per i dettagli).
Così, in origine, nel C89, era obbligatorio dichiarare tutte le variabili all'inizio di un blocco, come questo:
{
int a = 1;
a++;
/* ... */
}
Ciò implica direttamente una cosa molto importante: un blocco == un set immutabile di dichiarazioni variabili.
C99 ha cambiato questo. In essa è possibile dichiarare le variabili in qualsiasi parte del blocco, ma le dichiarazioni di dichiarazione sono ancora diverse dalle dichiarazioni regolari.
In effetti, per capire questo, è possibile immaginare che tutte le dichiarazioni di variabili vengano spostate implicitamente all'inizio del blocco in cui vengono dichiarate e rese non disponibili per tutte le istruzioni che le precedono.
Questo è semplicemente perché un blocco == un set di dichiarazioni regola ancora valida.
Ecco perché non è possibile "saltare sopra una dichiarazione". La variabile dichiarata esisterebbe ancora.
Il problema è l'inizializzazione. Non viene "spostato" da nessuna parte. equivalente Così, tecnicamente, per il vostro caso, i seguenti programmi potrebbero essere considerati:
goto later;
int a = 100;
later:
printf("%d", a);
e
int a;
goto later;
a = 100;
later:
printf("%d", a);
Come si può vedere, la dichiarazione è ancora lì, ciò che viene saltato è l'inizializzazione.
Il motivo per cui questo non funziona con gli VLA è che sono diversi.In breve, è perché questo è valido:
int size = 7;
int test[size];
Le dichiarazioni di VLA saranno, a differenza di tutte le altre dichiarazioni, comportarsi in modo diverso nelle diverse parti del blocco in cui sono dichiarate. In effetti, un VLA potrebbe avere layout di memoria completamente diversi a seconda di dove è stato dichiarato. Non puoi "spostarlo" fuori dal luogo in cui sei appena saltato.
Si può chiedere, "va bene, allora perché non farlo in modo che la dichiarazione non sia influenzata dal goto
"? Beh, saresti ancora ottiene casi come questo:
goto later;
int size = 7;
int test[size];
later:
Che cosa si aspetta in realtà questo per fare ..
Quindi, che vieta che salta sopra dichiarazioni VLA è lì per un motivo - è la più? decisione logica per trattare casi come quelli sopra semplicemente proibendoli del tutto.
@ Mints97 Ah, quindi se le istruzioni hanno i propri blocchi anche senza istruzioni composte? Presumo che sia la risposta quindi :) peccato non posso accettare i commenti – MinecraftShamrock
cosa intendi con questo? che cosa fare se le affermazioni hanno a che fare con questo? E i blocchi e le dichiarazioni composte sono più o meno gli stessi, IIRC – Mints97
@ Mints97 Voglio dire che le variabili dichiarate condizionatamente non vengono spostate all'inizio dell'intera funzione ma solo all'inizio del "blocco" condizionale in cui si trovano a destra? Quindi un'istruzione if senza un'istruzione composta rappresenterebbe anche un blocco di questo tipo. La mia comprensione è corretta? – MinecraftShamrock