ostrzeżenie gcc „” zostanie zainicjowane po „

228

Dostaję wiele ostrzeżeń z kodu innej firmy, którego nie mogę modyfikować. Czy istnieje sposób na wyłączenie tego ostrzeżenia lub przynajmniej wyłączenie go dla niektórych obszarów (takich jak #pragma push / pop w VC ++)?

Przykład:

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__
źródło
Czy możesz zamieścić kilka wierszy rzeczywistych ostrzeżeń? A także powiedz, czy jest to C, C ++, a jeśli masz źródło, czy ostrzeżenie pochodzi z procesu linkowania lub kompilacji?
csl

Odpowiedzi:

371

Upewnij się, że członkowie pojawiają się na liście inicjalizacyjnej w tej samej kolejności, w jakiej pojawiają się w klasie

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

lub możesz zawrócić -Wno-reorder

uray
źródło
91
Dlaczego to takie ważne? Dlaczego to ostrzeżenie istnieje?
Eloff,
40
@Eloff W niektórych przypadkach (nie zalecane), ba ainicjalizacji może zależeć od siebie. Naiwny użytkownik może próbować zmienić kolejność inicjalizacji, aby uzyskać pewien efekt, a Ostrzeżenie wyraźnie wyjaśni, że nie działa.
Gorpik
24
Więc kolejność deklaracji ma znaczenie semantyczne, nawet jeśli nie ma związku między deklaracjami? Jak bez sensu!
Cuadue
10
To nie wyjaśnia, dlaczego to ostrzeżenie istnieje i cytuje -Wno-reorderbez wspominania, jakie problemy mogą do tego doprowadzić. Wiem, że OP nie poprosił o żadne inne szczegóły, ale tak wysoko głosowanej odpowiedzi spodziewam się przynajmniej wspomnieć o kontekście i zastrzeżeniach. Czy nie powinniśmy odpowiadać na pytanie, które OP powinien napisać?
underscore_d
4
@ cp.engr członkowie są inicjowani w kolejności ich deklaracji, a nie w kolejności na liście inicjującej - więc jeśli inicjalizacja członka zależy od innej, ale deklaracje są zamieniane, więc zależne zostają zainicjowane po jego zależności, ktoś niedługo będzie bardzo źle, bo to czysty UB.
underscore_d
30

Możesz to wyłączyć za pomocą -Wno-reorder.

Lukáš Lalinský
źródło
17

Dla osób używających QT mających ten błąd, dodaj go do pliku .pro

QMAKE_CXXFLAGS_WARN_ON += -Wno-reorder
użytkownik1175197
źródło
7

use -Wno-reorder(man gcc jest twoim przyjacielem :))

LaszloG
źródło
6
Wow, znalazłeś nowy sposób na powiedzenie RT_M: MIYF (mężczyzna jest twoim przyjacielem) Jeśli nie masz nic przeciwko, zamierzam go użyć :)
Oren S
4

Jeśli widzisz błędy z nagłówków bibliotek i używasz GCC, możesz wyłączyć ostrzeżenia, włączając nagłówki używające -isystemzamiast -I.

Podobne funkcje istnieją w clang .

Jeśli używasz CMake, możesz określić SYSTEMdla include_directories.

Drew Noakes
źródło
Czy możesz wyjaśnić, jak „określić SYSTEM”?
einpoklum
1
Wystarczy umieścić ciąg „SYSTEM” na końcu include_directorieswiersza.
Drew Noakes,
1

Kolejność inicjalizacji nie ma znaczenia. Wszystkie pola są inicjowane w kolejności ich definicji w swojej klasie / strukturze. Ale jeśli kolejność na liście inicjalizacji jest inna, gcc / g ++ generuje to ostrzeżenie. Zmień tylko kolejność inicjalizacji, aby uniknąć tego ostrzeżenia. Ale nie można zdefiniować pola przy użyciu podczas inicjalizacji przed jego konstruowaniem. Będzie to błąd czasu wykonywania. Więc zmieniasz kolejność definicji. Bądź ostrożny i uważaj!

Anatolij
źródło
OP chciał wiedzieć, jak wyłączyć ostrzeżenie, a nie co to znaczy ani jak naprawić kod. W rzeczywistości post mówi, że kod jest stroną trzecią i nie można go modyfikować. Nie mogą zmienić kolejności definicji, a prawdopodobnie także kolejności inicjalizacji.
Tim Seguine
to bardzo dużo robi znaczenia, czy 2nd obiekt na liście Init jest initd od 1 obiektu, ale są one uznane za złą drogę w nagłówku. w takim razie sprawy mogą stać się bardzo dziwne.
underscore_d
0
Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

kolejność jest ważna, ponieważ jeśli a jest inicjowane przed b, a a zależy od b. pojawi się niezdefiniowane zachowanie.

Samuel
źródło