Die Option g ++ -Wall enthält -Wreorder. Was diese Option bewirkt, wird unten beschrieben. Mir ist nicht klar, warum es jemanden interessieren würde (insbesondere genug, um dies standardmäßig in -Wall einzuschalten).
-Wororder (nur C ++) Warnen, wenn die im Code angegebene Reihenfolge der Mitgliedsinitialisierer nicht stimmt stimmen mit der Reihenfolge überein, in der sie ausgeführt werden müssen. Zum Beispiel: struct A { int i; int j; A (): j (0), i (1) {} }; Der Compiler ordnet die Elementinitialisierer für i und j neu an Passen Sie die Deklarationsreihenfolge der Mitglieder an und senden Sie eine Warnung darauf bewirken. Diese Warnung wird von -Wall aktiviert.
c++
g++
compiler-warnings
Peeter Joot
quelle
quelle
-Werror=reorder
Antworten:
Erwägen:
Jetzt
i
wird auf einen unbekannten Wert initialisiert, nicht auf Null.Alternativ kann die Initialisierung von
i
einige Nebenwirkungen haben, für die die Reihenfolge wichtig ist. Z.Bquelle
i
es initialisiert ist1
). Hieri
wird auf initialisiertj
, was tatsächlich ein Problem zeigt.Das Problem ist, dass jemand möglicherweise die Liste der Mitgliedsinitialisierer im Konstruktor sieht und denkt, dass sie in dieser Reihenfolge ausgeführt werden (j zuerst, dann i). Sie sind nicht, sie werden in der Reihenfolge ausgeführt, in der die Mitglieder in der Klasse definiert sind.
Angenommen, Sie haben geschrieben
A(): j(0), i(j) {}
. Jemand könnte das lesen und denken, dass ich am Ende den Wert 0 habe. Das tut es nicht, weil Sie es mit j initialisiert haben, das Junk enthält, weil es selbst nicht initialisiert wurde.Die Warnung erinnert Sie an das Schreiben
A(): i(j), j(0) {}
, das hoffentlich viel fauler aussieht.quelle
Andere Antworten haben einige gute Beispiele geliefert, die die Option für eine Warnung rechtfertigen. Ich dachte, ich würde einen historischen Kontext liefern. Der Schöpfer von C ++, Bjarne Stroustrup, erklärt in seinem Buch Die Programmiersprache C ++ (3. Auflage, Seite 259):
quelle
Dies kann Sie beißen, wenn Ihre Initialisierer Nebenwirkungen haben. Erwägen:
Das Obige gibt "bar" und dann "foo" aus, obwohl man intuitiv davon ausgehen würde, dass die Reihenfolge der in der Initialisierungsliste angegebenen entspricht.
Alternativ, wenn
x
undy
mit einem Konstruktor ein benutzerdefinierter Typ vorliegt, kann dieser Konstruktor auch Nebenwirkungen haben, mit demselben nicht offensichtlichen Ergebnis.Es kann sich auch manifestieren, wenn der Initialisierer für ein Mitglied auf ein anderes Mitglied verweist.
quelle
Die Warnung ist vorhanden, denn wenn Sie nur den Konstruktor lesen, sieht es so aus,
j
als würde er zuvor initialisierti
. Dies wird zu einem Problem, wenn einer zum Initialisieren des anderen verwendet wird, wie inWenn Sie sich nur den Konstruktor ansehen, sieht dies sicher aus. In Wirklichkeit wurde
j
es jedoch noch nicht an dem Punkt initialisiert, an dem es zum Initialisieren verwendet wirdi
, sodass der Code nicht wie erwartet funktioniert. Daher die Warnung.quelle