Table of Contents
Статический анализ кода C++
Для меня красота C++ заключается в первую очередь во вседозволенности и ужасающей мощи языка. Мы можем работать с памятью так же плотно, как и в C, и в то же время имеем такие средства, как шаблоны и STL, превосходящие по уровню абстрактности все, что я когда-либо видел. Плата за это соответствующая - не всегда вразумительные ошибки компилятора (попробуйте забыть поставить точку с запятой после определения класса), очень большой срок подготовки и обучения программистов, но самое главное - некоторые баги становятся заметными только во время выполнения программы.
О проблеме
Мы хотим больше полезных ворнингов до выполнения наших программ. Одно из средств получения желаемого - статический анализ кода. Статический - значит, не запуская программу. Интересны не только вероятные ошибки, случаи undefined behaviour, утечки памяти, но и вещи вроде недоступности/неиспользуемости кода, рекомендации по повышению интуитивности стиля программирования. Средства получения метрик ПО, добываемых методами статического анализа в этой статье не рассматриваются. Замечания, связанные со стандартами программирования (фигурная скобочка должны находиться на отдельной строчке, ууууу!!) тоже не интересны. Критерии оценки простые - количество и полезность находимых багов, простота использования (в частности, отсутствие требований модификации кода), бесплатность/разумная цена/хороший кряк. Проводи первичный обзор и выдаем на-гора пачку ссылок:
Найденные штуки
Педантичные ключи gcc
- -Wall включает все ворнинги, среди которых совместимость с новым стандартом, границы массива (по-моему, не пашет, хотя говорят, что будет работать с -O2), valatile/register переменные (сообщит, что ему пофигу на твои умные слова и что register, а что нет, он будет решать сам), точки следования (i++ + ++i)
- -Wextra - еще пачка ворнингов типа пустых тел в if'ах, сравнение signed и unsigned
- -pedantic – следование ISO C++ стандарту
- -Weffc++ must have опция. Не включается via Wextra или Wall и содержит проверку рекомендаций Скотта Мейерса:
Item 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory.
Item 12: Prefer initialization to assignment in constructors. Item 14: Make destructors virtual in base classes. Item 15: Have "operator=" return a reference to *this. Item 23: Don't try to return a reference when you must return an object. Item 6: Distinguish between prefix and postfix forms of increment and decrement operators. Item 7: Never overload "&&", "||", or ",".
- -Woverloaded-virtual - перегрузка виртуальных фунций
- -Wctor-dtor-privacy - неиспользуемые классы – с приватным конструкторами и деструктором
- -Wnon-virtual-dtor – невиртуальный деструктор! Смотри-ка, сделали!
- -Wold-style-cast - приведение в стиле C - это плохо
- -Werr='тип ворнинга' - воспринимать ворнинг как еррор. Для настроящих самураем -Werr без параметров
- -Winit-self – int i = i;
- -Wunreachable-code - код, который никогда не будет выполнен
Cppcheck
Пожалуй, самая достойна из найденных программ. cpp check и его плагин для эклипсоидов. Распознает довольно много, находит следующие ошибки:
- некоторые memory leaks, например, отсутствие delete и delete[], отсутствие delete в деструкторе
- выход за границу массива
- exception'ы, бросаемые в деструкторе
- разыменование нулевого указателя
- разыменование после очистки памяти
- виртуальность деструктора базового класса
- использование одного и того же итератора для разных контейнеров
- разные более мелкие штуки
Проверялки для C без плюсов
Удивительно, но программисты на чистом Си, похоже, больше заботятся о статическом анализе. Тут мы имеем:
- http://www.cert.org/secure-coding/tools.html – список раз
Будут ли они полезны плюсовым разработчикам? Если у вас есть код без классов и вы помните, какие программы на C++ не будут собираться компилятором С, то почему бы и нет?
Splint
- Вот такая штука для чистого C. Собирается не без усилий, но работает чистенько и много чего ищет - смотри мануал
Simian
- similarity analyzer – ищет дублирование кода
Vera++
- Vera++. В отличие от cppcheck, ориентированиа на проверку стиля. Имеет пополняемую базу правил. По умолчанию в базе много реально идиотстких штук типа “перед двоеточием должен быть пробел”. Единственная полезная возможность – запрет на использование using namespace в заголовочных файлах. Правила, однако можно писать и самому на языке Tcl. :)
- RATS -рассказывает страшилки про безопасность и buffer overflow-атаки
- CIL компилирует C в упрощенный C! Упрощенный C уже можно скармливать другим анализаторам
Непонятное, офтопное
- Oink требует Flex и Bison, долго догадывался.. (: А еще надо фиксить кучу ошибок при компиляции. Ниасилил скомпилять, а список фич отнюдь не внушительный
- Mozilla Dehydra – нечто, базируещееся на этом самом Oink'е
- Mozilla Pork ниасилил установку
- Еще есть компиляторы, которые предоставляют больше ворнингов на основе статического анализа. Например Rose
- Rational Purify - прославленная компания IBM Rational имеет свой набор инструментов для статического и динамического анализа. Буду рад, если кто-нибудь расскажем об этой программе, триальник для линукса у них оказался только для x64-архитектуры.
Триальное/крякнутое ПО
А мало его такого. Много анализаторов, стоящих много долларов и не имеют кряков. Вот пример такого анализатора, можно зайти на их сайт и попросить триальник Cleanscape
Что бы еще хотелось
Хотелось бы:
- Политику спецификации исключений как в Java.
- юзанье auto_ptr в контейнерах STL, разыменование auto_ptr после присвоения другому auto_ptr.
- using namespace в h-файлах
- размещающий delete без new или new без delete
- вызов delete[] для немассивов
- = вместо == в if'ах