Il seguente C++ esempio fallisce la compilazione con gcc o suono metallico, ma genera solo un avvertimento con ICC, e niente affatto con MSVC:errore: salta all'etichetta 'foo' attraversa inizializzazione di 'bar'
int main(int argc, char *argv[])
{
if (argc < 2)
goto clean_up;
#if 1 // FAIL
int i = 0;
#elif 0 // workaround - OK
{
int i = 0;
}
#else // workaround - OK
int i;
i = 0;
#endif
clean_up:
return 0;
}
g ++:
init.cpp:13: error: jump to label ‘clean_up’
init.cpp:4: error: from here
init.cpp:7: error: crosses initialization of ‘int i’
clang ++:
init.cpp:4:9: error: cannot jump from this goto statement to its label
goto clean_up;
^
init.cpp:7:9: note: jump bypasses variable initialization
int i = 0;
^
ICC:
init.cpp(4): warning #589: transfer of control bypasses initialization of:
variable "i" (declared at line 7)
goto clean_up;
^
Capisco la causa dell'errore, e per un semplice esempio come questo è abbastanza facile da aggirare (ho incluso un paio di soluzioni alternative nell'esempio sopra), ma sto lavorando a una grande base di codice legacy multipiattaforma che è costellata di macro di gestione degli errori che utilizzano un costrutto simile goto
. Altri sviluppatori che lavorano con MSVC o ICC continuano a introdurre inizializzazioni inline che successivamente causano errori nelle build di gcc o clang (e ovviamente ignorano semplicemente gli avvertimenti che ottengono con MSVC/ICC).
Quindi ho bisogno di trovare un modo per (a) fare in modo che tali casi si traducano in errori su ICC/MSVC o (b) ridurli agli avvisi con gcc/clang. Ho provato -fpermissive
con gcc ma questo non sembra essere d'aiuto.
Per il credito supplementare Sono anche curioso di vedere la logica dietro questo errore per una semplice inizializzazione scalari - Posso capire perché saltando un costruttore potrebbe essere problematico, ma l'inizializzazione di un
int
come nell'esempio di cui sopra non sembra come potrebbe mai essere un problema, e semplicemente scindendo la definizione + inizializzazione in una definizione + assegnazione fa sparire l'errore?
In C, questo è consentito (anche se disapprovato). Non sono sicuro di C++. – Bathsheba
Gli sviluppatori dovrebbero correggere anche gli avvisi del compilatore, non solo gli errori. – Melebius
@Bathsheba: sì, questi legacy macro vengono originariamente da una base in codice C, ma ora il codice C++ viene sempre più utilizzato e continuo a dover risolvere ogni nuova occorrenza di questo problema. –