﻿# Cppcheck

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

Сайт проекта: [http://cppcheck\.sourceforge\.net/](http://cppcheck.sourceforge.net/)

Cppcheck является открытым, бесплатным инструментом, распространяемым под лицензией GNU General Public License\. Организатором проекта является Daniel Marjamäki \(его [профиль на сайте Stack Overflow](https://stackoverflow.com/users/823177/daniel-marjam%c3%a4ki)\)\. Исходный код проекта можно [скачать](https://github.com/danmar/cppcheck/) с сайта github\.

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

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

* **Code::Blocks** \- integrated
* **CodeLite** \- integrated
* **Eclipse** \- [Cppcheclipse](https://github.com/kwin/cppcheclipse)
* **Jenkins** \- [Cppcheck Plugin](https://plugins.jenkins.io/cppcheck/)
* **Visual Studio / Eclipse** \- [Visual Lint](https://www.riverblade.co/products/visual_lint/) by RiverBlade \(платное решение\)

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

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

![Cppcheck_ru/image2.png](https://import.viva64.com/docx/blog/Cppcheck_ru/image2.png)

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

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

![Cppcheck_ru/image3.png](https://import.viva64.com/docx/blog/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\)\.

![Cppcheck_ru/image4.png](https://import.viva64.com/docx/blog/Cppcheck_ru/image4.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\)", то происходит утечка памяти\.

```cpp
....
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' а только несколько первых байт\.

```cpp
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\.

```cpp
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

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

```cpp
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\(\) печатает два числа, а параметров передаётся три\. Или один параметр лишний, или неправильная строка форматирования\.

```cpp
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

## Ссылки

1. Website: [http://cppcheck\.sourceforge\.net/](http://cppcheck.sourceforge.net/)
1. Wikipedia: [Cppcheck](https://en.wikipedia.org/wiki/Cppcheck)\.
1. Cppcheck manual: [HTML](http://cppcheck.sourceforge.net/manual.html), [PDF](http://cppcheck.sourceforge.net/manual.pdf)\.
1. Cppcheck [git repository](https://github.com/danmar/cppcheck/)\.
1. Пример положительного отзыва о Cppcheck\. [Cppcheck: free, easy, and great](http://www.realtimerendering.com/blog/cppcheck-free-easy-and-great/)\.
1. Евгений Рыжков\. [Сравнение Cppcheck и PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/0149/)\.
1. Aleksey Vitebskiy\. [Poor Man's Visual Studio Cppcheck Integration](https://www.codeproject.com/tips/472065/poor-man-s-visual-studio-cppcheck-integration)\.