Предупреждения компилятора (Compiler warnings) — это сообщения компилятора о подозрительных местах в программе, которые могут содержать ошибки. В отличие от ошибок компиляции, предупреждения не прерывают процесс сборки программы. Они не являются ошибками с точки зрения языка программирования, но могут быть программными ошибками. Впрочем, многие компиляторы можно настроить так, чтобы предупреждения останавливали процесс компиляции.
Предупреждения не стоит игнорировать. Лучше исправить возможные ошибки ещё до начала тестирования программы. Можно долго и упорно искать ошибку в отладчике, хотя про неё явно сообщает компилятор в одном из предупреждений. Следует стараться, чтобы при работе с проектом все предупреждения были устранены, или их было минимальное количество. Чем меньше предупреждений, тем легче замечать и обрабатывать новые (см. также "Теория разбитых окон").
Различные компиляторы выдают свои предупреждения основываясь на собственном статическом анализе кода, выполняемом на этапе компиляции. Поэтому предупреждения, выдаваемые MSVC и GCC или Clang, могут различаться. К сожалению, компилятор не в силах провести полноценный анализ, поскольку компиляция должна выполняться быстро. Поэтому для поиска более сложных ошибок в программе лучше воспользоваться специализированными инструментами статического анализа кода.
Бывают ситуации, когда всё же нужно подавить выдаваемые компилятором предупреждения. Часто это случается при использовании сторонних библиотек и включении расширенного вывода ошибок.
Подавление на уровне кода подразумевает внесение изменений в исходный код. Конкретный способ подавления зависит от компилятора, но все они опираются на один и тот же механизм — связку #pragma push и #pragma pop.
MSVC:
#pragma warning(push)
#pragma warning(disable : %WARN%)
// correct code generating the warning %WARN%
#pragma warning(pop)
Clang:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-W${WARN}"
// correct code generating the warning ${WARN}
#pragma clang diagnostic pop
GCC:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-W${WARN}"
// correct code generating the warning ${WARN}
#pragma GCC diagnostic pop
Обратите внимание, что Clang также понимает инструкции подавления от GCC.
Часто бывает так, что нет возможности внести изменения в код с предупреждениями. В таком случае можно воспользоваться способами ниже.
Данным способом можно выключить определённые диагностики сразу на всем проекте. Списки с идентификаторами и названиями всех диагностик расположены в конце.
MSVC:
Добавить в опции компиляции флаг /wd%WARN_ID%. Например:
/wd4820
GCC и Clang:
Добавить в опции компиляции флаг -Wno-${WARN_NAME}. Например:
-Wno-unused-comparison
Обратите внимание, что если вам нужно подавить предупреждения только на файлах из определённой директории (библиотеки), то лучше использовать способ ниже.
Большинство компиляторов не выдают предупреждения на системном коде. Можно воспользоваться этим свойством, чтобы убрать предупреждения, на которые мы не можем повлиять. Данный способ зависит от используемой системы сборки и компилятора, поэтому покажем только наиболее распространённые варианты.
CMake:
Необходимо использовать инструкцию target_include_directories. Главное — добавить параметр SYSTEM перед необходимым путём. Например, так:
target_include_directories(my_target SYSTEM /path/to/lib)
MSVC:
Можно воспользоваться флагом компиляции /external. Подробнее про него и его применение можно узнать из документации.
GCC and Clang:
При указании путей поиска файлов необходимо использовать флаг -isystem. Например:
-isystem /path/to/lib
Список источников
0