Чому варто відключити попередження компілятора?


26

Ця відповідь та додані до неї коментарі показують спосіб відключення декількох попереджень компілятора за допомогою #pragmaдиректив.

Навіщо хотіти цього робити? Зазвичай попередження існують не просто так, і я завжди вважав, що вони є вагомими причинами. Чи є якийсь "дійсний випадок", коли попередження слід вимкнути? Зараз я не можу придумати жодного, але, можливо, це тільки я.


4
Не впевнений, чому хтось позначив це близько. Мені це здається надзвичайно розумним питанням. +1

@Alastair Pitts: Я запропонував міграцію програмістам. Пізніше я зрозумів свою помилку.
Тугрул Атес

3
Попереджувальні повідомлення є з тієї причини, так, але є також причина, чому вони не є повідомленнями про помилки .
Соломон повільно

2
@jameslarge Ваш коментар добре підводить ситуацію. Попередження - це компілятор, який повідомляє вам, що ситуація, правдоподібно, неправильна , що означає, що можливо, правильно . Якщо це було точно не так, то це була б помилка. Оскільки деякі попередження можуть бути помилковими, завжди повинен бути спосіб записати код таким чином, щоб він усував попередження. На жаль, іноді найпрагматичніший спосіб зробити це через прагму; звідси і назва.
Ерік Ліпперт

Це не відключає, це ховається. Проблема все ще буде там, що ви її не побачите так, як є
Сисір,

Відповіді:


11

У мене коли-небудь була одна ситуація, коли я відключив попередження. Я вважаю помилки попереджень, тому зазвичай не випускаю їх із попередженнями. Однак, розробляючи API у клієнтів, я стикався з тим, що метод, який був необхідний на етапі міграції однією програмою і який ніколи інший не повинен використовувати, не повинен включатися до бібліотеки.

Найкращий спосіб, який я міг би сказати всім користувачам API, що вони не повинні називати цей метод, - це позначити його застарілим. Однак це означало, що один дійсний випадок використання позначений як попередження про компіляцію.

Ерік Ліпперт написав кілька публікацій про попередження, де ви знайдете інформацію про те, як команда компілятора думає про попередження.

Внутрішні поля внутрішніх типів

Не використовувані директиви не позначаються попередженнями


10

Ось кілька попереджень, де в документації наведено причини, чому ви можете їх відключити:

Інші приклади включають попередження про використання методів амортизації, якщо ви знаєте, що ви все ще хочете використовувати старий метод або мати приватних членів, які ніколи не читаються локально, а натомість з відображенням.

На мій досвід, у C # є менше потреби у відключенні попереджень, ніж у інших мовах, таких як C ++. Це багато в чому тому, що, як каже Ерік Ліпперт у своєму блозі , вони "намагаються зарезервувати попередження лише для тих ситуацій, коли ми можемо з впевненістю сказати, що код порушений, введений в оману або марний".


3
Приємно. Я думаю, що перший є найяснішим, тому що він містить дуже конкретний випадок і виправдання (третій, наприклад, показує код коду, який ніколи не пройде огляд моєї команди). Це запитання говорить про застарілі / втрачені попередження. По суті, вони все ще потрібні в застарілому коді, але ви хочете відмовити будь-якому новому коду від їх використання. У застарілому коді повинні бути подані попередження.
Грег Джексон

Я багато робив макро програмування в excel, і мені довелося вимкнути попередження з різних причин, таких як автоматичне збереження, автоматичний вихід, сповіщення тощо. Звичайно, ви можете не знати про ці попередження ...
Дейв Мес

@ICR Я взагалі не пам’ятаю, щоб відключити попередження компілятора на Java. Все, що я роблю, - це уникати використання застарілих методів.
Махмуд Хоссам

@Mahmoud Мені дуже часто доводиться придушувати "неперевірені" попередження, роблячи що-небудь навіть віддалено складне з генериками. Але, мабуть, несправедливо забивати Java в C ++ на фронті смішних попереджень - відредагував мою відповідь.
ICR

@ICR Java застосовує використання дженерики для забезпечення безпеки типу в колекціях, хоча деякі розглядають це як обмеження, я вважаю це особливістю, це робить код написання трохи болісним, але це рятує життя, і так, вихід компілятора C ++ дещо страшно, якщо мова йде про STL або що-небудь із шаблонами.
Махмуд Хоссам

8

Приклад на мові C, що я регулярно зустрічаю варіанти:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

Аргумент доречний лише на деяких платформах, але на тих, де це не доречно, мій компілятор поскаржиться, і оскільки у мене є попередження, перетворені на помилки, це запобіжить його нарощуванню.

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


6

Багато незамінних бібліотек Java ніколи не оновлювались, щоб усунути потребу в небезпечних наборах передач. Придушення цих попереджень необхідно, щоб інші важливіші попередження були помічені та виправлені.


5

Я займаюся вбудованою роботою і, здається, пам’ятаю час або два, коли я відключав попередження, тому що робив щось, що виглядало марно для компілятора, але що насправді мало реальні ефекти на апаратному забезпеченні.

Єдиний інший час, коли я працюю над кодовими базами з різними уявленнями про якусь структуру даних (наприклад, як представити масиви байтів - char чи неподписані char?). У цих випадках я можу вимкнути попередження, оскільки альтернативою є провести дні, переглядаючи код і змінивши одну частину, або розмістивши сотні записів.


3

Існує досить багато причин вибіркового відключення попереджень компілятора, навіть для проектів, які прагнуть до кращих практик.

  • Різні компілятори (або різні версії одних і тих же компіляторів) :
    Компілятори обробляють попередження дуже тонко. Надання помилково-позитивних попереджень, які не впливають на інших компіляторів. У цьому випадку може бути доцільним відключити попередження для цих компіляторів, замість редагування дійсного коду, щоб замовчувати помилково-позитивне попередження, яке впливає лише на певні компілятори, особливо для старих компіляторів, які з часом стануть непідтримуваними.
  • З генерованим кодом:
    Деякі попередження, пов’язані з гігієною коду (мертвий код, дублікат масиву умовних заяв, порівняння, що перевищують обмеження типу), можна сміливо ігнорувати, оскільки вони нешкідливі, і компілятор оптимізує їх.
    Генерування коду, який не викликає цих нешкідливих попереджень, звичайно, також є варіантом, але може бути більше проблем, ніж його варто.
  • Попередження для зовнішнього коду.
    Можливо, ви використовуєте добре відому реалізацію контрольної суми qsort або md5, яка включена у ваш проект. Код використовується багатьма проектами, і він, як відомо, добре працює, але можуть бути деякі прискіпливі попередження, які зазвичай правильний для вашого власного коду.
    Щодо зовнішнього коду, можливо, буде менше клопоту просто відключити попередження (припустимо, що його, безумовно , нешкідливо).
  • Попередження, викликані заголовками системи:
    Незважаючи на те, що GCC / Clang, наприклад, підтримує -isystem, бувають випадки, коли відмінності в заголовках системи викликають попередження, які можна ігнорувати (можливо, функція має підписане значення повернення в одній системі, але не інша), викликаючи -Wsign-compareпопередження.
    Іншим випадком можуть бути макроси, визначені в заголовках системи, ви можете скопіювати і вставити макроси у свій власний код, щоб змінити їх, але всі речі вважають за краще не турбуватися про збереження макросів з сторонніх бібліотек ... так що краще просто щоб увімкнути попередження (можливо, макрос пропускає причину виклику-Wsign-conversion наприклад).
  • Невикористані застереження в коді заглушки:
    Ви можете попередити про невикористані параметри, однак, коли заглушка цілої бібліотеки в один файл, який містить лише функції заглушки, - це не корисно для застосування (void)arg1; (void)arg2; (void)arg3; ...в тілі кожної функції заглушки.
    Краще просто придушити -Wunused-parameterв цьому випадку.

Зверніть увагу , що у всіх цих прикладах, презюміруемого відключення попереджень не збирається приховувати реальні помилки, наприклад: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, можливо , -Wpedantic... і що ви знаєте , що ви робите!


2

Дійсна чи ні, іноді це робиться для обходу директиви "трактувати попередження як помилки" на сервері збірки.

Крім цього я не можу придумати жодного. Попередження для інвалідів, як правило, є ознакою "некрасивого ганьби" ...


2

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

Тим часом нам потрібно було скомпілювати його, і ми хотіли, щоб варіант "попередження є помилками" увімкнено, тому ми придушили деякі попередження.


2

Наразі єдине попередження, яке я коли-небудь ігнорую, - це

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Оскільки microsoft не реалізує специфікацію C ++ (документація навіть говорить, що вони не роблять!) І дозволяє функціям оголошувати конкретні кидки, і всі функції можуть лише кидати () або кидати (...), тобто нічого або все.

З HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.