Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Итак, вы хотите заглушить это предупреж…

Итак, вы хотите заглушить это предупреждение в Visual C++...

21 Авг 2013

Обычная ситуация: вы написали кусок безупречно правильного кода, но Visual C++ выдает на нем предупреждение. Часто можно немного переписать код, чтобы предупреждение ушло, но не всегда, и тогда выход один - глушить выдачу этого предупреждения. Рассмотрим, какие возможности для этого есть в Visual C++ и какие ошибки допускают при их использовании.

Статью написал сотрудник компании ABBYY Дмитрий Мещеряков, впервые опубликована: "Блог компании ABBYY. Итак, вы хотите заглушить это предупреждение в Visual C++..." Публикуется здесь с разрешения правообладателя.

Мы решили опубликовать эту статью в базе знаний, так как она очень хорошо поясняет назначение диагностики V665, реализованную в PVS-Studio.

Самая очевидная первая возможность - запретить предупреждение в настройках проекта на уровне проекта. Это работает, но плохо. Во-первых, предупреждение будет заглушено во всем проекте, в том числе и во всех заголовках, которые этот проект включает в себя. Во-вторых, если вы скопируете код в другой проект, предупреждение появится снова. Это неизбежно произойдет в случае кода в заголовочных файлах (например, содержащими реализацию шаблонов), который необходимо включать (#include) в каждый проект, который их использует.

Следующая возможность - запретить предупреждение в настройках проекта на уровне файла. Этот способ еще хуже предыдущего. Во-первых, предупреждение будет заглушено на всю единицу трансляции, т.е. в этом файле и всех заголовках, которые он включает. Во-вторых, точно те же проблемы с копированием кода, что и в прошлый раз. В-третьих, как только в проекте оказывается больше нескольких файлов, вероятность потерять эту настройку при конверсии проекта под более новую версию Visual C++ становится равной чуть менее, чем единице.

Остается использование #pragma warning. Обычно ее используют так:

#pragma warning (disable: 9000)
// код, провоцирующий предупреждение C9000
#pragma warning (default: 9000)

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

На самом деле, это FAIL. Пора внимательно прочитать (да, внимательно и да, прочитать, а не копипастить код откуда попало) описание #pragma warning (default). Там говорится следующее: эта конструкция

  • Устанавливает предупреждению уровень по умолчанию и
  • Включает предупреждение.

Сначала уровни. В Visual C++ с каждым предупреждением связано число от 1 до 4 - это уровень предупреждения. Предупреждения уровня 1 считаются более серьезными, с ростом уровня серьезность якобы снижается. У каждого предупреждения есть уровень по умолчанию. Конструкция

#pragma warning(Level: Warning)

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

У компилятора есть настройка, с какого уровня предупреждения показывать, Warning Level. При значении этой настройки, равном A, предупреждение в конкретной строке кода показывается только в том случае, если оно там разрешено и его уровень составляет A или ниже.

Кроме того, в Visual C++ часть предупреждений по умолчанию выключена, потому что они выдаются даже в самом безобидном коде и все от них устали. Пусть каждый, кто собирается возмутиться самой идеей точечного подавления конкретного предупреждения, для начала осознает и прочувствует этот факт.

Рассмотрим, как проявляется FAIL при использовании #pragma warning (default).

FAIL 1. Предупреждение C9001 выключено по умолчанию. Код в заголовочном файле использует #pragma warning(default:9001), чтобы "восстановить" предупреждение, заглушенное в небольшом куске кода.

Зачем он это делает, если предупреждение и так выключено? Список предупреждений, выключенных по умолчанию, меняется от одной версии Visual C++ к другой - в него понемногу добавляются предупреждения. Если код изначально писали для Visual C++ 7, а там C9001 по умолчанию было включено, а теперь компилируют в Visual C++ 10, и в нем предупреждение уже выключено, то такая конструкция смысла не имеет, а могла просто достаться в наследство.

В результате #pragma warning(default) принудительно включает предупреждение, выключенное по умолчанию.

FAIL 2. У предупреждения C9002 уровень по умолчанию 3, а проект компилируется с уровнем 2, т.е. "показывать предупреждения уровня 2 и ниже". После долгих раздумий разработчики решили, что на самом деле предупреждение C9002 достаточно серьезное, чтобы удостоить его уровня 2, т.е. принудительно повысить серьезность. Соответственно, каждый проект включает в себя стандартный заголовок, попадающий затем во все единицы трансляции, который содержит конструкцию #pragma warning(2:9002).

Чуть ниже по тексту в единице трансляции оказывается #pragma warning(default:9002), которая сбрасывает уровень обратно на 3, и при компиляции с уровнем 2 предупреждение не выдается. Кстати, это предупреждение сообщало о серьезном дефекте. Улыбаемся и машем. В обратную сторону тоже работает — предупреждению "повысили" уровень с 2 до 3, чтобы оно не выдавалось в проектах, компилируемых с уровнями 2 и ниже (т.е. понизили серьезность), но #pragma warning(default) сбрасывает уровень на 2, и предупреждение выдается.

FAIL 3. Предупреждение C9003 по умолчанию включено, но продумано так плохо, что никто не может припомнить, когда оно выдается по делу. Разработчики решаются заглушить его повсюду, использовав #pragma warning(disable:9003) в общем заголовочном файле. Ниже по единице трансляции оказывается #pragma warning(default:9003), которая включает предупреждение.

Что особенно приятно, эти ситуации возникают в самый подходящий момент - при переходе с одной версии компилятора на другую, при попытке включить в проект кучу стороннего кода, который и без того не прост в использовании, вторая ситуация просто приводит к подавлению предупреждения, в результате можно пропустить ошибку в коде, которая позже поможет пользователям получить премию Дарвина.

На самом деле, предупреждения нужно глушить так:

#pragma warning(push)
// хорошие, годные вакансии: www.abbyy.ru/vacancy
#pragma warning(disable:9000)
// код с предупреждением C9000
#pragma warning(pop)

Первая конструкция сохраняет текущее состояние настроек предупреждений, вторая отключает нужное предупреждение, третья - восстанавливает сохраненное состояние. При этом состояние восстанавливается полностью - все сделанные уровнями выше изменения тоже восстанавливаются, предупреждения, выключенные по умолчанию, не включаются.

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

Популярные статьи по теме
Обрабатывать ли в PVS-Studio вывод других инструментов?

Дата: 26 Май 2022

Автор: Андрей Карпов

Анализатор PVS-Studio умеет "схлопывать" повторяющиеся предупреждения. Предоставляет возможность задать baseline, что позволяет легко внедрять статический анализ в legacy-проекты. Стоит ли предостави…
15000 ошибок в открытых проектах

Дата: 24 Май 2022

Автор: Андрей Карпов

Количество багов в нашей коллекции перевалило за отметку 15000. Именно такое количество ошибок обнаружила команда PVS-Studio в различных открытых проектах. Особенно интересно, что это всего лишь побо…
Комментарии в коде как вид искусства

Дата: 04 Май 2022

Автор: Сергей Хренов

Приветствую всех программистов, а также сочувствующих. Кто из нас хотя бы раз в жизни не оставлял комментарии в коде? Был ли это ваш код, а может, чужой? Что за комментарии вы написали: полезные или …
Visual Studio 2022 стильно и свежо. История о её поддержке в PVS-Studio

Дата: 15 Фев 2022

Автор: Николай Миронов

Кажется, анонс Visual Studio 2022 был только недавно, и вот она уже вышла. Это означало ровно одно – поддержать данную IDE нужно в ближайшем релизе PVS-Studio. О том, с какими сложностями пришлось ст…
Лучшие срабатывания статического анализатора

Дата: 29 Окт 2021

Автор: Максим Звягинцев

У всех, кто запускал статический анализатор в первый раз на большом проекте, был небольшой шок по поводу сотен, тысяч или даже десятков тысяч предупреждений. Как-то грустно становится после такого. Т…

Комментарии (0)

Следующие комментарии
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять