Почему нужно отключить предупреждения компилятора?


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 или unsigned char?). В этих случаях я мог бы отключить предупреждения, потому что альтернатива состоит в том, чтобы провести дни, просматривая код и изменяя одну часть, или вводя сотни приведений.


3

Существует довольно много причин, чтобы выборочно отключать предупреждения компилятора, даже для проектов, которые стремятся к лучшей практике.

  • Разные компиляторы (или разные версии одних и тех же компиляторов) :
    компиляторы обрабатывают предупреждения тонко по-разному. Давать ложноположительные предупреждения, которые не влияют на другие компиляторы. В этом случае может иметь смысл отключить предупреждение для этих компиляторов, вместо того, чтобы редактировать действительный код, чтобы отключить ложноположительное предупреждение, которое воздействует только на определенные компиляторы, особенно для старых компиляторов, которые в конечном итоге в любом случае станут неподдерживаемыми.
  • С сгенерированным кодом:
    некоторые предупреждения, относящиеся к гигиене кода (мертвый код, дублирующее тело условных операторов, сравнения, превышающие пределы типов), можно безопасно игнорировать, поскольку они безвредны, и компилятор их оптимизирует.
    Генерирование кода, который не вызывает этих безвредных предупреждений, конечно, тоже вариант, но может быть больше проблем, чем стоит.
  • Предупреждения для внешнего кода:
    возможно, вы используете хорошо известную реализацию контрольной суммы qsort или md5, которая включена в ваш проект. Код используется многими проектами и, как известно, работает хорошо, но могут быть некоторые придирчивые предупреждения, которые вы обычно исправляете для своего собственного кода.
    Для внешнего кода , однако, может быть меньше хлопот , просто отключить предупреждение (при условии его определенно является безвредным).
  • Предупреждения, вызванные системными заголовками:
    несмотря на то, что, например -isystem, GCC / Clang поддерживают , различия в системных заголовках вызывают предупреждения, которые можно игнорировать (возможно, функция имеет возвращаемое значение со знаком в одной системе, но не в другой), вызывая -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 ++ (в документации даже сказано, что они этого не делают!) И позволяет функциям объявлять конкретные броски, а все функции могут бросать только throw () или throw (...), т.е. ничего или все.

Из 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.