2015-07-20 7 views
6

Das folgende C++ Beispiel nicht kompiliert, sondern erzeugt nur eine Warnung mit ICC, und gar nichts mit MSVC:Fehler: Sprung mit gcc oder Klappern, beschriften ‚foo‘ kreuzen Initialisierung von ‚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’ 

Klirren ++:

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:

Ich verstehe die Ursache des Fehlers, und für ein einfaches Beispiel wie dies ist es ziemlich einfach zu umgehen (ich habe ein paar mögliche Umgehungsmöglichkeiten im obigen Beispiel enthalten), aber ich arbeite daran eine große Cross-Plattform-Legacy-Codebasis, die mit Fehlerbehandlungsmakros gespickt ist, die ein ähnliches goto-Konstrukt verwenden. Andere Entwickler, die mit MSVC oder ICC arbeiten, führen immer Inline-Initialisierungen ein, die in der Folge zu Fehlern bei gcc- oder clang-Builds führen (und ignorieren natürlich nur die Warnungen, die sie mit MSVC/ICC erhalten).

Also muss ich einen Weg finden, um entweder (a) solche Fälle zu Fehlern auf ICC/MSVC zu bringen oder (b) sie auf Warnungen mit gcc/clang zu reduzieren. Ich versuchte -fpermissive mit gcc, aber das scheint nicht zu helfen.


Für zusätzliche Kredite bin ich auch in Bezug auf die Gründe für diesen Fehler für die einfache skalare Initialisierung neugierig - kann ich sehen, warum über einen Konstruktor springen könnte problematisch sein, aber eine int wie im obigen Beispiel scheint nicht initialisiert Wie könnte es jemals ein Problem sein, und einfach die Definition + Initialisierung in eine Definition + Zuordnung aufteilen lässt den Fehler weg?

+0

In C ist dies erlaubt (obwohl verpönt). Nicht sicher über C++. – Bathsheba

+1

Entwickler sollten auch ihre Compiler-Warnungen beheben, nicht nur Fehler. – Melebius

+0

@Bathsheba: Ja, diese Legacy-Makros stammen ursprünglich aus einer C-Code-Basis, aber jetzt wird zunehmend C++ - Code verwendet und ich muss jedes neue Auftreten dieses Problems beheben. –

Antwort

2

Das MSVC-Flag zur Behandlung einer Warnung als Fehler ist /we n, wobei n die Nummer der Warnung ist.

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

Weitere Informationen finden Sie unter https://msdn.microsoft.com/en-us/library/thxezb7y.aspx.

+0

Schließen - es sieht so aus, als wäre 'C2362' die entsprechende Warnung/der Fehler, aber' cl' generiert das nicht, es sei denn, Sie verwenden '/ Za', scheint es, in diesem Fall ist es sowieso ein Fehler. Die Verwendung von '/ Za' ist leider keine Option, da es viele andere Dinge kaputt macht. Hmmm ... –

+0

'/ Za' scheint die Microsoft-Erweiterungen des C++ - Standards zu deaktivieren. https://msdn.microsoft.com/en-us/library/0k0w269d.aspx Sie müssen entscheiden, ob Sie Microsoft-Erweiterungen verwenden, oder kompilieren Sie mit GCC ... – Melebius

+0

Ja, leider '/ Za' bricht eine Menge unserer bestehenden Code (Code, der OK mit allen anderen Compilern kompiliert), so ist es keine Option. Dies ist einer der großen Probleme mit älteren Codebasen - Sie können Dinge nicht einfach "reparieren". –