2015-07-20 14 views
6

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?

+0

In C, questo è consentito (anche se disapprovato). Non sono sicuro di C++. – Bathsheba

+1

Gli sviluppatori dovrebbero correggere anche gli avvisi del compilatore, non solo gli errori. – Melebius

+0

@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. –

risposta

2

Il flag MSVC per il trattamento di un avviso come errore en è /we n dove n è il numero dell'avviso.

For example, /we4326 flags warning number C4326 as an error.

Vedere https://msdn.microsoft.com/en-us/library/thxezb7y.aspx per dettagli.

+0

Chiudi: sembra che 'C2362' sia l'avviso/errore appropriato, ma' cl' non lo genera a meno che non si usi '/ Za', nel qual caso si tratta comunque di un errore. Sfortunatamente usare '/ Za' non è un'opzione, poiché rompe molte altre cose. Hmmm ... –

+0

'/ Za' sembra disabilitare le estensioni Microsoft dello standard C++. https://msdn.microsoft.com/en-us/library/0k0w269d.aspx Devi decidere se usare le estensioni Microsoft o compilare con GCC ... – Melebius

+0

Sì, sfortunatamente '/ Za' rompe molto del nostro codice esistente (codice che compila OK con tutti gli altri compilatori), quindi non è un'opzione. Questo è uno dei grossi grattacapi con basi di codice legacy - non puoi "aggiustare" le cose. –

Problemi correlati