gcc warning "'wird nach' initialisiert

228

Ich erhalte viele dieser Warnungen von Code von Drittanbietern, die ich nicht ändern kann. Gibt es eine Möglichkeit, diese Warnung zu deaktivieren oder zumindest für bestimmte Bereiche zu deaktivieren (z. B. #pragma push / pop in VC ++)?

Beispiel:

list.h:1122: warning: `list<LogOutput*, allocator<LogOutput*> >::node_alloc_' will be initialized after 
list.h:1117: warning:   `allocator<LogOutput*> list<LogOutput*, allocator<LogOutput*> >::alloc_'
LK__
quelle
Können Sie bitte ein paar Zeilen der tatsächlichen Warnungen posten? Und sagen Sie auch, ob dies C, C ++ ist und ob Sie die Quelle haben, ob die Warnung vom Linker oder vom Kompilierungsprozess stammt?
CSL

Antworten:

371

Stellen Sie sicher, dass die Mitglieder in der Initialisierungsliste in derselben Reihenfolge angezeigt werden, in der sie in der Klasse angezeigt werden

Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

oder du kannst dich umdrehen -Wno-reorder

uray
quelle
91
Warum ist das übrigens wichtig? Warum gibt es diese Warnung?
Eloff
40
@Eloff In einigen Fällen (nicht zu empfehlen), bund aInitialisierung könnte voneinander abhängig sind . Ein naiver Benutzer könnte versuchen, die Initialisierungsreihenfolge zu ändern, um einen Effekt zu erzielen, und die Warnung würde deutlich machen, dass dies nicht funktioniert.
Gorpik
24
Die Reihenfolge der Deklarationen hat also eine semantische Bedeutung, auch wenn zwischen den Deklarationen keine Beziehung besteht? Wie sinnlos!
Cuadue
10
Dies erklärt nicht, warum diese Warnung existiert und zitiert, -Wno-reorderohne zu erwähnen, zu welchen Problemen dies führen könnte. Ich bin mir bewusst, dass das OP keine weiteren Details angefordert hat, aber eine so hoch bewertete Antwort würde ich erwarten, zumindest den Kontext und die Vorbehalte dazu zu erwähnen. Sollten wir nicht die Frage der OP beantworten sollte geschrieben haben?
underscore_d
4
@ cp.engr-Mitglieder werden in der Reihenfolge ihrer Deklaration initialisiert, nicht in der Reihenfolge in der Init-Liste. Wenn also die Initialisierung eines Mitglieds von einem anderen abhängt, die Deklarationen jedoch ausgetauscht werden, wird das Abhängige nach seiner abhängigen Person initialisiert wird sehr bald eine sehr schlechte Zeit haben, da das reine UB ist.
underscore_d
30

Sie können es mit deaktivieren -Wno-reorder.

Lukáš Lalinský
quelle
17

Wenn Sie QT mit diesem Fehler verwenden, fügen Sie dies der .pro-Datei hinzu

QMAKE_CXXFLAGS_WARN_ON += -Wno-reorder
user1175197
quelle
7

benutze -Wno-reorder(man gcc ist dein Freund :))

LaszloG
quelle
6
Wow, du hast einen neuen Weg gefunden, um RT_M zu sagen: MIYF (Mann ist dein Freund) Wenn es dir nichts ausmacht, werde ich es benutzen :)
Oren S
4

Wenn Sie Fehler in Bibliotheksheadern sehen und GCC verwenden, können Sie Warnungen deaktivieren, indem Sie die Header -isystemanstelle von verwenden -I.

Ähnliche Merkmale gibt es in Clang .

Wenn Sie CMake verwenden, können Sie SYSTEMfür angeben include_directories.

Drew Noakes
quelle
Können Sie erklären, wie man "spezifiziert SYSTEM"?
Einpoklum
1
Setzen Sie einfach die Zeichenfolge "SYSTEM" am Ende der include_directoriesZeile.
Drew Noakes
1

Die Reihenfolge der Initialisierung spielt keine Rolle. Alle Felder werden in der Reihenfolge ihrer Definition in ihrer Klasse / Struktur initialisiert. Wenn die Reihenfolge in der Initialisierungsliste jedoch unterschiedlich ist, wird diese Warnung von gcc / g ++ generiert. Ändern Sie nur die Initialisierungsreihenfolge, um diese Warnung zu vermeiden. Sie können das Feld jedoch nicht in der Initialisierung vor seinem Konstrukt definieren. Es wird ein Laufzeitfehler sein. Sie ändern also die Reihenfolge der Definition. Sei vorsichtig und pass auf!

Anatoly
quelle
Das OP wollte wissen, wie die Warnung deaktiviert werden kann, nicht was sie bedeutet oder wie der Code repariert werden kann. In der Tat heißt es in dem Beitrag, dass der Code von Dritten stammt und nicht geändert werden kann. Sie können die Reihenfolge der Definition und wahrscheinlich auch nicht die Reihenfolge der Initialisierung ändern.
Tim Seguine
es sehr viel tut ganz gleich , ob das zweite Objekt in der init - Liste aus dem ersten Objekt initd ist, aber sie sind falsch herum im Header deklarieren. In diesem Fall könnten die Dinge sehr seltsam werden.
underscore_d
0
Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

Die Reihenfolge ist wichtig, denn wenn a vor b initialisiert wird und a von b abhängt. undefiniertes Verhalten wird angezeigt.

Samuel
quelle