PVS-Studio - это инструмент для выявления ошибок в исходном коде программ, написанных на языках С, C++ и C#.
PVS-Studio выполняет статический анализ кода и генерирует отчёт, помогающий программисту находить и устранять ошибки. PVS-Studio выполняет широкий спектр проверок кода, но наиболее силён в поисках опечаток и последствий неудачного Copy-Paste. Показательные примеры таких ошибок: V501, V517, V522, V523, V3001.
Анализатор ориентирован на разработчиков, использующих среду Visual Studio, и может в фоновом режиме выполнять анализ измененных файлов после их компиляции. В идеале ошибки будут обнаружены и исправлены ещё до попадания в репозиторий. Однако ничто не мешает использовать анализатор для проверки всего решения целиком или для встраивания в системы непрерывной интеграции. Эти и иные способы использования анализатора описаны в документации.
PVS-Studio выполняет статический анализ кода и генерирует отчёт, помогающий программисту находить и устранять ошибки. PVS-Studio выполняет широкий спектр проверок кода, но наиболее силён в поисках опечаток и последствий неудачного Copy-Paste. Показательные примеры таких ошибок: V501, V517, V522, V523, V3001.
Анализатор ориентирован на разработчиков, использующих среду Visual Studio, и может в фоновом режиме выполнять анализ измененных файлов после их компиляции. В идеале ошибки будут обнаружены и исправлены ещё до попадания в репозиторий. Однако ничто не мешает использовать анализатор для проверки всего решения целиком или для встраивания в системы непрерывной интеграции. Эти и иные способы использования анализатора описаны в документации.
Опечатки в Miranda IM
Запись от el_programmer размещена 30.05.2016 в 16:24
Показов 2377
Комментарии 0
Метки bugs, c++, cpp, miranda, open source, programming
|
Автор: Александр Чибисов Статья посвящена часто встречающимся ошибкам, возникающим из-за опечаток на примере проекта Miranda IM. Многие подобные ошибки могут привести к некорректному поведению программы, а некоторые из них не наносят явного вреда, но приводят к ухудшению понятности кода. Введение Miranda IM известная программа обмена мгновенными сообщениями. Исходный код программы был взят мною из репозитория SourceForge, где доступны все версии исходников программы. Для проверки использовалась версия Miranda IM 0.10.50 и анализатор PVS-Studio версии 6.03. Проект уже анализировался ранее, и о результатах можно почитать в заметке "Как уменьшить вероятность ошибки на этапе написания кода". В исходном коде Miranda IM анализатор указал на многие проблемные места. Среди сообщений анализатора попадались и такие, которые невозможно точно идентифицировать как ошибочные, возможно это просто слишком хитрый код. Для статьи такие фрагменты не подходят, и поэтому были выбраны только наиболее интересные из ошибок. Некорректное освобождение памяти
Анализатор оповещает об ошибке работы с памятью при уничтожении объекта. В случае, когда в списке нет элементов функция завершится преждевременно, при этом память, выделенная под массив recentEntries будет очищена некорректно. В то же время, если функция будет исполнена до конца, то объект будет уничтожен правильно, именно поэтому данную ошибку можно отнести к категории опечаток. При создании массива с помощью new[] для корректного уничтожения и очистки памяти необходимо использовать команду delete[]. Использование функции free совместно с оператором new недопустимо. При очистке памяти функция free не вызывает деструкторы объектов, что может привести к неопределённому поведению программы. Да и само по себе такое освобождение памяти, уже является неопределённым поведением. Для исправления ошибки необходимо привести код к единому виду и заменить функцию free на оператор delete[]. Несоблюдение приоритета операций Приоритет операций очень важен. Часто из-за несоблюдения приоритета происходят ошибки в расчётах или конструкция ведёт себя совсем не так, как ожидает программист.
Фрагмент кода показывает, как неверно поставленная закрывающаяся скобка, привела к ошибке в работе тернарного оператора. Так как оператор побитового ИЛИ имеет больший приоритет чем тернарный оператор сначала вычисляется выражение MF_BYCOMMAND | (nen_options.bTraySupport)и только после этого полученное значение сравнивается внутри тернарной конструкции. Для исправления ошибки код следует изменить следующим образом.
Ещё один пример связанный с неверным приоритетом операций:
Здесь при проверке второго выражения вместо применения оператора логического отрицания к выражению tmp->state == GG_STATE_WAITING_FOR_ACCEPTпроверка применяется к переменой tmp->state и только после этого сравнивается с константой GG_STATE_WAITING_FOR_ACCEPT. Для исправления ошибки требуется взять второе выражение в скобки и условие изменится следующим образом:
"Потерянное выражение"
По приведённому фрагменту видно, что функция создана для удаления маски по ID. Если количество масок больше единицы, то требуется уменьшать счётчик масок mmTemplateList->dwMaskCnt. В данном случае код был просто скопирован из нижней части функции и в результате лишняя строчка с декрементом счётчика была исправлена некорректно. Вероятнее всего выражение требуется изменить на:
Похожая ошибка с потерянным значением цвета фона была обнаружена в другом участке кода. Но упомяну о ней только в виде диагностического сообщения.
Лишнее присваивание
Присваивание значения нескольким переменным сразу допустимы в языке С++. Это достаточно удобно при использовании коротких переменных в небольших функциях. Но в больших фрагментах кода такая запись ухудшает читаемость кода и ведёт к появлению дополнительных ошибок. Здесь явно видна ошибка, произошедшая в результате копирования кода, так как в этом же проекте лежит другая версия плагина на языке C и там используется следующая строка кода:
Исправить код возможно следующим образом:
Присваивание в условии Присваивание в условии не всегда является ошибкой, но может привести к большим сложностям при изменениях и проверках кода. Данная ошибка часто преследовала меня после перехода на C++ с другого языка программирования. Её достаточно сложно заметить при обычной проверке кода, а компилятор Visual C++ сообщает о подобных ошибках только если присваивается результат выполнения функций. Но анализатор работает более внимательно и может выявить все случаи подобных ошибок.
Приведённый фрагмент показывает ситуацию, когда присваивание внутри условия приводит к преждевременному выходу из функции. Данная функция предназначена для поиска элемента и внутри переменной хранится ссылка на него, но из-за ошибки внутри условия значение переменой перезаписывается. В результате функция всегда будет выдавать одинаковый результат независимо от того, был найден элемент или нет. Похожий фрагмент присутствует ещё в одном месте.
Повтор в условии Похожие ошибки в программах встречаются достаточно часто. В небольших фрагментах обнаружить повторы достаточно просто, а вот в условиях с большим количеством проверок они теряются из виду. Именно в таких случаях для поиска ошибки поможет статический анализ кода. Приведу несколько примеров данной ошибки.
Из приведённого кода видно, что переменная job->hOwner проверяется дважды. Скорее всего во втором случае переменную следует изменить на job->hwndOwner, так как именно с ней продолжается работа внутри условного блока. В другом примере, найденном диагностикой V501, явно видно место повтора в условии.
В данном случае ошибка не является критичной, так как до проверки третьего аргумента в условии программа никогда не дойдёт. Но это не значит, что данный фрагмент кода не нуждается в исправлении: необходимо убрать лишнее выражение !ppUserListиз условия. Нужны ли скобки?
По данному коду сложно установить какая именно ошибка перед нами. Скорее всего обе команды должны выполняться только при выполнении условия. В этом случае код работает некорректно и для его исправления необходимо добавить фигурные скобки вокруг блока операторов. Дополнительно, для улучшения читаемости кода стоит разделить операторы на несколько строк.
Излишние проверки
Часто подобные ошибки свидетельствуют об опечатках в именах переменных или логических ошибках, но в данном случае это просто избыточный код. По приведённому фрагменту видно, что внутри вложенного условия проверяются те же выражения, что уже были проверены во внешнем блоке. Подобная проверка не имеет смысла, так как вложенное условие будет всегда истинно. Анализатор обнаружил ещё несколько избыточных условий.
Условные блоки, выполняющие одинаковый код Такой код чаще всего освидетельствует о наличии логической ошибки. Но бывают и другие ситуации, которые не всегда можно трактовать как ошибку.
В данном случае условный блок скорее всего был сделан для поддержания стиля кода. Или данные блоки должны были служить для обработки ошибок, но так и не были дописаны. Именно поэтому блоки кода выглядят подозрительно, и на них стоит обратить внимание. В проекте Miranda IM встречается достаточно много таких блоков, и их лучше показать просто списком.
Заключение Miranda IM развивается уже не так быстро, как раньше, но в проекте ещё много неисправленных ошибок разного уровня опасности. Это показывает, что статический анализ кода важен на любом этапе развития проекта. Анализатор PVS-Studio поможет найти весьма заковыристые и подлые ошибки. Если вы разрабатываете проект на C, C++ или C#, предлагаю не откладывая скачать PVS-Studio и проверить свой проект. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Метки bugs, c++, cpp, miranda, open source, programming
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии


