Cppcheck

Cppcheck - это инструмент статического анализа исходного кода на языке Си и Си++. Отличительными чертами инструмента являются: открытость, бесплатность, кроссплатформенность, простота использования.

Сайт проекта: http://cppcheck.sourceforge.net/

Cppcheck является открытым, бесплатным инструментом, распространяемым под лицензией GNU General Public License. Организатором проекта является Daniel Marjamäki (его профиль на сайте StackOverflow). Исходный код проекта можно скачать с сайта github.

Возможности Cppcheck

На момент написания этой заметки Cppcheck версии 1.60.1 поддерживал следующие языки: C89, C99, C11, C++03, C++11. Также, на момент написания статьи, существуют следующие плагины для интеграции с различными средами разработки:

Использование Cppcheck

Одним из основных преимуществ анализатора Cppcheck является простота использования. Можно рекомендовать этот инструмент для обучения и первого знакомства с методологией статического анализа. Например, установив Cppcheck для Windows, вы получаете GUI интерфейс, позволяющий сразу приступить к проверке ваших проектов.

https://import.viva64.com/docx/terminology/Cppcheck_ru/image1.png

Рисунок 1. Cppcheck для Windows. Главное окно. Нажмите на картинку для увеличения.

Просто выберите в меню "Check directory" и укажите путь до вашего проекта. Результат работы анализатора может выглядеть как показано на рисунке ниже.

https://import.viva64.com/docx/terminology/Cppcheck_ru/image3.png

Рисунок 2. Результат проверки проекта. Нажмите на картинку для увеличения.

Конечно, я немного лукавлю, говоря, что Cppcheck не требует никакой настройки. Если вы серьезно начнете использовать Cppcheck, вам понадобится произвести ряд настроек. Например, потребуется указать пути до сторонних библиотек, интегрировать Cppcheck с вашей средой разработки или настроить ночные запуски. Однако, сам факт, что вы можете просто выбрать каталог и получить результат - очень здорово! Особенно если вы только начинаете изучать, что такое статический анализ кода. Эта возможность просто бесценна.

После проверки можно просмотреть диагностические сообщения. Все сообщения разделены на следующие группы: Errors, Warnings, Style Warnings, Portability Warnings, Performance Warnings, Information Messages. Группы легко включать/выключать используя кнопки на тулбаре.

На рисунке N3 показан режим работы для просмотра Style Warnings. Группа предупреждений "Style Warnings" включена, а остальные выключены (см. цифру 1). Файл "cpuid_x86.c" содержит несколько таких предупреждений. Выбрано первое предупреждение, которое относится к 214 строке (см. цифру 2). В нижнем окне сразу показывается описание этой диагностики (см. цифру 3).

https://import.viva64.com/docx/terminology/Cppcheck_ru/image5.png

Рисунок 3. Пример просмотра диагностического сообщения. Нажмите на картинку для увеличения.

Диагностики

Анализатор Cppcheck выполняет множество различных видов проверок. Перечислим некоторые из них:

  • Неправильное использование функций из Standard Template Library;
  • Утечки памяти (Memory leaks);
  • Утечки ресурсов (Resource leaks);
  • Выход за границы массивов (Bounds checking for array overruns);
  • Использование неинициализированных переменных;
  • Использование устаревших функций;
  • Проверка операций ввода/вывода (Check input/output operations);
  • Разыменование нулевого указателя.

Примеры диагностик

Приведём несколько примеров ошибок в коде, которые умеет выявлять анализатор Cppcheck.

Пример N1. Проект MPlayer

В этом коде ситуация отсутствия данных обрабатывается неправильно. Если выполняется условие "(!sh->wf || sh->wf->cbSize < 80)", то происходит утечка памяти.

....
context_t *ctx = calloc(1, sizeof(context_t));
const SpeexMode *spx_mode;
const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT;
if (!sh->wf || sh->wf->cbSize < 80) {
  mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n");
  return 0;
}
....

Диагностическое сообщение:

libmpcodecs/ad_speex.c:44: Memory leak: ctx

Пример N2. Проект Doom 3

В коде вместо "sizeof(ctx)" должно быть написано "sizeof(*ctx)". Из-за ошибки обнуляется не весь объект 'ctx' а только несколько первых байт.

void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) {
  ....
  memset( ctx, 0, sizeof( ctx ) );

Диагностическое сообщение:

..\Doom3\id-Software-DOOM-3-a9c49da\neo\idlib\hashing\MD5.cpp(252):

Using size of pointer ctx instead of size of its data.

Пример N3. Проект Doom 3

Ошибка связана с тем, что память выделяется для массива элементов, а освобождается, как если бы она была выделена для одного элемента. Правильный вариант delete [] sortIndex.

void idImageManager::PrintMemInfo( MemInfo_t *mi ) {
  int *sortIndex;
  ....
  sortIndex = new int[images.Num()];
  ....
  delete sortIndex;

Диагностическое сообщение:

..\Doom3\id-Software-DOOM-3-a9c49da\neo\renderer\Image_init.cpp(2214)

Mismatching allocation and deallocation: sortIndex

Пример N4. Проект Quake 3: Arena

Массив состоит из трех элементов. А работаем, как если бы он содержал четыре элемента.

void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
{
  ...
  unsigned char invModulate[3];
  ...
  invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
  invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
  invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
  invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
  // this trashes alpha, but the AGEN block fixes it

Диагностическое сообщение:

..\Quake3\id-Software-Quake-III-Arena-dbe4ddb\code\renderer\tr_shade_calc.c 628

Array 'invModulate[3]' index 3 out of bounds

Пример N5. Проект Quake 3: Arena

Функция printf() печатает два числа, а параметров передаётся три. Или один параметр лишний, или неправильная строка форматирования.

static void do_uid(int x) {
  printf("<a href='#%d'>%d</a>", x, x, x);
}

Диагностическое сообщение:

..\Quake3\id-Software-Quake-III-Arena-dbe4ddb\lcc\src\2html.c 131

printf format string has 2 parameters but 3 are given

Ссылки


Найденные ошибки

Проверено проектов
409
Собрано ошибок
14 072

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

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