gcc warning "'sera initialisé après'

228

Je reçois beaucoup de ces avertissements du code tiers que je ne peux pas modifier. Existe-t-il un moyen de désactiver cet avertissement ou au moins de le désactiver pour certaines zones (comme #pragma push / pop dans VC ++)?

Exemple:

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__
la source
Pouvez-vous s'il vous plaît poster quelques lignes des avertissements réels? Et dites aussi si c'est C, C ++, et si vous avez la source, si l'avertissement vient du lieur ou du processus de compilation?
csl

Réponses:

371

Assurez-vous que les membres apparaissent dans la liste d'initialisation dans le même ordre qu'ils apparaissent dans la classe

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

ou vous pouvez tourner -Wno-reorder

uray
la source
91
Pourquoi est-ce important btw? Pourquoi cet avertissement existe-t-il?
Eloff
40
@Eloff Dans certains cas (pas recommandé), bet l' ainitialisation peuvent dépendre les uns des autres. Un utilisateur naïf pourrait essayer de modifier l'ordre d'initialisation pour obtenir un certain effet et l'avertissement indiquerait clairement que cela ne fonctionne pas.
Gorpik
24
Donc, l'ordre des déclarations a une signification sémantique, même s'il n'y a pas de relation entre les déclarations? C'est inutile!
Cuadue
10
Cela n'explique pas pourquoi cet avertissement existe et cite -Wno-reordersans mentionner les problèmes qui pourraient en résulter. Je suis conscient que le PO n'a pas demandé d'autres détails, mais une réponse tellement votée que je m'attendrais à mentionner au moins le contexte et les mises en garde à ce sujet. Ne sommes-nous pas censés répondre à la question que le PO aurait dû écrire?
underscore_d
4
Les membres @ cp.engr sont initialisés dans l'ordre de leur déclaration, et non dans leur ordre dans la liste init - donc, si l'initialisation d'un membre dépend d'un autre, mais les déclarations sont échangées de sorte que le dépendant soit initialisé après sa personne à charge, quelqu'un va très bientôt passer un très mauvais moment, car c'est du pur UB.
underscore_d
30

Vous pouvez le désactiver avec -Wno-reorder.

Lukáš Lalinský
la source
17

Pour ceux qui utilisent QT ayant cette erreur, ajoutez ceci au fichier .pro

QMAKE_CXXFLAGS_WARN_ON += -Wno-reorder
user1175197
la source
7

utiliser -Wno-reorder(man gcc est votre ami :))

LaszloG
la source
6
Wow, vous avez trouvé une nouvelle façon de dire RT_M: MIYF (l'homme est votre ami) Si cela ne vous dérange pas, je vais l'utiliser :)
Oren S
4

Si vous voyez des erreurs des en-têtes de bibliothèque et que vous utilisez GCC, vous pouvez désactiver les avertissements en incluant les en-têtes à la -isystemplace de -I.

Des caractéristiques similaires existent dans clang .

Si vous utilisez CMake, vous pouvez spécifier SYSTEMpour include_directories.

Drew Noakes
la source
Pouvez-vous expliquer comment "spécifier SYSTEM"?
einpoklum
1
Mettez simplement la chaîne `SYSTEM` à la fin de la include_directoriesligne.
Drew Noakes
1

L'ordre d'initialisation n'a pas d'importance. Tous les champs sont initialisés dans l'ordre de leur définition dans leur classe / structure. Mais si l'ordre dans la liste d'initialisation est différent, gcc / g ++ génère cet avertissement. Modifiez uniquement l'ordre d'initialisation pour éviter cet avertissement. Mais vous ne pouvez pas définir le champ using dans l'initialisation avant sa construction. Ce sera une erreur d'exécution. Vous changez donc l'ordre de définition. Soyez prudent et restez attentif!

Anatoly
la source
L'OP voulait savoir comment désactiver l'avertissement, pas ce que cela signifie ou comment corriger le code. En fait, la publication indique que le code est tiers et ne peut pas être modifié. Ils ne peuvent pas non plus changer l'ordre de définition et probablement pas l'ordre d'initialisation.
Tim Seguine
il est très bien fait importe si le 2ème objet dans la liste init est initd à partir du 1er objet, mais ils sont déclarés dans le mauvais sens dans l' en- tête. dans ce cas, les choses pourraient devenir très étranges.
underscore_d
0
Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

l'ordre est important car si a est initialisé avant b, et a dépend de b. un comportement indéfini apparaîtra.

Samuel
la source