gcc попередження "" буде ініціалізовано після "


228

Я отримую багато цих попереджень із коду сторонньої сторони, який я не можу змінити. Чи є спосіб відключити це попередження або принаймні відключити його для певних областей (наприклад, #pragma push / pop у VC ++)?

Приклад:

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_'

Чи можете ви надішліть, будь ласка, пару рядків фактичних попереджень? А також скажіть, чи це C, C ++, і якщо у вас є джерело, якщо попередження надходить від лінкера чи процесу компіляції?
csl

Відповіді:


371

Переконайтесь, що члени відображаються у списку ініціалізатора в тому ж порядку, що і у класі

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

або можна повернути -Wno-reorder


91
Чому це важливо? Чому це попередження існує?
Елофф

40
@Eloff У деяких випадках (не рекомендується) bі aініціалізація може залежати одна від одної. Наївний користувач може спробувати змінити порядок ініціалізації, щоб отримати певний ефект, і Попередження дасть зрозуміти, що це не працює.
Горпик

24
Отже, порядок декларацій має смислове значення, навіть якщо між деклараціями немає зв’язку? Як безглуздо!
Куадуе

10
Це не пояснює, чому це попередження існує та цитується, -Wno-reorderне згадуючи, які проблеми можуть призвести. Я знаю, що ОП не запитувала жодних інших подробиць, але я б очікував, що принаймні згадую контекст та попередження щодо цього. Чи ми не повинні відповідати на питання, яке повинно було написати ОП ?
підкреслити_20

4
@ cp.engr члени ініціалізуються в порядку їх декларації, а не їх порядку в init-списку - так, якщо ініціалізація члена залежить від іншого, але декларації заміняються, так що залежний стає ініціалізованим після залежного, когось матиме дуже поганий час дуже скоро, оскільки це чистий UB.
підкреслюй_d



7

використання -Wno-reorder(людина gcc - твій друг :))


6
Нічого собі, ви знайшли новий спосіб сказати RT_M: MIYF (чоловік - ваш друг) Якщо ви не заперечуєте, я збираюся його використати :)
Oren S

4

Якщо ви бачите помилки в заголовках бібліотеки та використовуєте GCC, ви можете відключити попередження, включивши заголовки -isystemзамість, а не -I.

Подібні особливості існують і в кланге .

Якщо ви використовуєте CMake, ви можете вказати SYSTEMдля include_directories.


Чи можете ви пояснити, як «вказати SYSTEM»?
einpoklum

1
Просто поставте рядок `SYSTEM` в кінці include_directoriesрядка.
Дрю Ноакс

1

Порядок ініціалізації не має значення. Усі поля ініціалізуються в порядку їх визначення у своєму класі / структурі. Але якщо порядок у списку ініціалізації інший gcc / g ++, генеруйте це попередження. Змініть лише порядок ініціалізації, щоб уникнути цього попередження. Але ви не можете визначити використання поля при ініціалізації перед його побудовою. Це буде помилка виконання. Отже, ви змінюєте порядок визначення. Будьте уважні і бережіть увагу!


ОП хотіла знати, як відключити попередження, а не те, що воно означає, або як виправити код. Насправді у публікації йдеться про те, що код є стороннім і не може бути змінений. Вони також не можуть змінити порядок визначення і, ймовірно, також не порядок ініціалізації.
Тім Сегейн

він дуже робить справу , якщо другий об'єкт в списку ініціалізації є initd з 1 - го об'єкта, але вони оголосили неправильний шлях навколо в заголовку. у цьому випадку все може стати дуже дивним.
підкреслюй_

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

порядок важливий, тому що якщо a ініціалізується перед b, а a залежить від b. з’явиться невизначена поведінка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.