Опция g ++ -Wall включает в себя -Wreorder. Что эта опция делает, описано ниже. Для меня не очевидно, почему кого-то это волнует (особенно достаточно, чтобы включить это по умолчанию в -Wall).
-Заказ (только C ++) Предупреждать, когда порядок инициализаторов членов, указанный в коде, не соответствовать порядку, в котором они должны быть выполнены. Например: структура А { int i; int j; A (): j (0), i (1) {} }; Компилятор переставит инициализаторы членов для i и j в соответствовать порядку декларации членов, выдавая предупреждение эффект. Это предупреждение включено -Wall.
c++
g++
compiler-warnings
Питер Джут
источник
источник
-Werror=reorder
Ответы:
Рассматривать:
Теперь
i
инициализируется неким нулевым значением.Альтернативно, инициализация
i
может иметь некоторые побочные эффекты, для которых важен порядок. Напримеристочник
i
инициализируется до1
). Здесьi
инициализируется доj
, что фактически демонстрирует проблему.Проблема в том, что кто-то может увидеть список инициализаторов членов в конструкторе и подумать, что они выполняются в таком порядке (сначала j, затем i). Это не так, они выполняются в том порядке, в котором члены определены в классе.
Предположим, вы написали
A(): j(0), i(j) {}
. Кто-то может прочесть это и подумать, что я заканчиваю со значением 0. Это не так, потому что вы инициализировали его с помощью j, который содержит мусор, потому что он сам не был инициализирован.Предупреждение напоминает вам написать
A(): i(j), j(0) {}
, что, надеюсь, выглядит более подозрительно.источник
Другие ответы предоставили несколько хороших примеров, которые оправдывают возможность предупреждения. Я думал, что предоставлю некоторый исторический контекст. Создатель C ++ Бьярн Страуструп объясняет в своей книге « Язык программирования C ++» (3-е издание, стр. 259):
источник
Это может укусить вас, если ваши инициализаторы имеют побочные эффекты. Рассматривать:
Выше будет напечатано «bar», а затем «foo», хотя интуитивно можно предположить, что порядок такой же, как и в списке инициализатора.
В качестве альтернативы, если
x
иy
имеют некоторый пользовательский тип с конструктором, этот конструктор также может иметь побочные эффекты с тем же неочевидным результатом.Это также может проявиться, когда инициализатор для одного члена ссылается на другого члена.
источник
Предупреждение существует, потому что если вы просто читаете конструктор, похоже, что
j
он инициализируется раньшеi
. Это становится проблемой, если один используется для инициализации другого, как вКогда вы просто смотрите на конструктор, это выглядит безопасно. Но на самом деле, он
j
еще не был инициализирован в точке, где он используется для инициализацииi
, и поэтому код не будет работать должным образом. Отсюда и предупреждение.источник