2014-01-08 8 views
5

Ich habe ein Stück Code, das fein kompiliert, wenn ich es in dieser Form schreiben (mit -Wjump-misses-init flag):Warum gibt GCC mir die Warnung -Wjump-Misses-Init?

int some_function(void) { 

     ... 

     if (is_error) 
       goto error; 

     int a; 

     a = 1; 

     return a; 

error: 
     return 666; 
} 

Aber wenn ich die gleiche Funktion in dieser Form schreiben erhalte ich die unten Warnung, wenn ich kompilieren (?:

int some_function(void) { 

     ... 

     if (is_error) 
       goto error; 

     int a = 1; 

     return a; 

error: 
     return 666; 
} 

test.c: In function 'some_function': 
test.c:15:17: warning: jump skips variable initialization [-Wjump-misses-init] 
test.c:21:1: note: label 'error' defined here 
test.c:17:13: note: 'a' declared here 

Warum GCC mir nicht geben diese Warnung, wenn ich erklären und initialisieren a auf der gleichen Linie scheint ein wenig seltsam für mich Diese Beispiele sind unsinnig, aber ich fürchte, ich bin nicht in Freiheit? Veröffentlichen Sie das echte Code-Snippet. Ich verwende GCC 4.7.2 auf Debian Wheezy 7.3.

EDIT: void Typo

+2

In C++ darf [eine Deklaration mit Initialisierung nicht überspringen] (http://stackoverflow.com/questions/20963288/c-conditional-storage-allocation-for-object-craced-by-scope/20963326) # 20963326), aber ich habe Probleme, die gleiche Aussage in C99 zu finden. –

+0

Ich frage mich, ob der Fehler mit verschiedenen Optimierungsflags gehalten wird. Oder wenn die Montage anders ist. Vielleicht ist die Reihenfolge der Operationen in einem Fall etwas anders. Es ist nur eine wilde Vermutung. – luk32

+0

Auch "int void" sieht wie ein Tippfehler aus. –

Antwort

2

In C++ Sie bypasses declarations with initialization sind nicht erlaubt, aber es scheint in C99 erlaubt zu werden. Sie können gcc warnen, wenn Sie entweder -Wjump-misses-init oder -Wc++-compat verwenden. Dies wird im Abschnitt gcc docs bedeckt Options to Request or Suppress Warnings und sagt:

Warnen, wenn eine goto-Anweisung oder eine switch-Anweisung springt nach vorn über die Initialisierung einer Variable oder springt rückwärts auf ein Etikett nach der Variable initialisiert wurde. Dies warnt nur bei Variablen, die bei ihrer Deklaration initialisiert werden. Diese Warnung wird nur für C und Objective-C unterstützt. In C++ ist diese Art von Verzweigung in jedem Fall ein Fehler.

-Wjump-misses-init ist in -WC++ enthalten - compat. Es kann mit der Option -Wno-jump-misses-init deaktiviert werden.

Hinweis, dies gilt auch für Deklarationen in einem Schalter Anweisung. Eine Möglichkeit, dies zu umgehen, ist das Erstellen eines neuen Bereichs unter Verwendung von {}.

Im Anhang ich die draft C99 standard dies als Warnung vermuten lässt, heißt es:

Eine Implementierung Warnungen in vielen Situationen erzeugen kann, von denen keine als Teil dieser Internationalen Norm festgelegt sind. Die folgenden sind einige der häufigsten Situationen.

und umfasst die folgenden Aufzählungs:

Ein Block mit der Initialisierung eines Objekts, das automatische Speicherdauer hat gesprungen in (6.2.4).

+0

Interessant, '-Wjump-Misses-init' ist nicht in' -WC++ - compat' für meine Version von gcc (4.8 .1, Ubuntu 12.04). Wurde es entfernt? – ecatmur

+0

@ecatmur hmmm, scheint so in '4.8' zu sein, obwohl' 4.7' es immer noch hat. –

1

Wenn Sie die a Variable verwenden sind nach error: Etikett auf den Sprung, würde sein Wert unbestimmt (6.2.4p6); Dies ist möglicherweise verwirrend, weshalb gcc davor warnt. (Es ist auch illegal in C++.)

die Warnung und noch Deklaration-Initialisierung verwenden, um zu vermeiden, können Sie Code in einem Block wickeln:

int some_function(void) { 
    { 
     ... 

     if (is_error) 
       goto error; 

     int a = 1; 

     return a; 
    } 
error: 
    return 666; 
} 

In diesem Fall müssen Sie außerhalb des Blockes alle Variablen, die Sie nach der Verwendung erklären error: Etikett.

Verwandte Themen