Для меня красота C++ заключается, в первую очередь, во вседозволенности и ужасающей мощи языка. Мы можем работать с памятью так же плотно, как и в C, и в то же время имеем такие средства абстракции, как шаблоны и STL, где параметризовать можно что угодно и чем угодно.
Плата за это соответствующая — не всегда вразумительные ошибки компилятора (попробуйте забыть поставить точку с запятой после определения класса), очень большой срок подготовки и обучения программистов, но самое главное — некоторые баги становятся заметными только во время исполнения программы.
Мы хотим больше полезных ворнингов до запуска наших программ. Одно из средств получения желаемого — статический анализ кода. Статический — значит, не запуская программу. Интересны не только вероятные ошибки, случаи undefined behaviour, утечки памяти, но и вещи вроде недоступности/неиспользуемости кода, рекомендации по повышению интуитивности стиля программирования.
Средства получения метрик ПО, добываемых методами статического анализа в этой статье не рассматриваются. Замечания, связанные со стандартами программирования (фигурная скобочка должна находиться на отдельной строчке, ууууу!!) тоже не интересны.
Критерии оценки простые — количество и полезность находимых багов, простота использования (в частности, отсутствие требований модификации кода), бесплатность/разумная цена/хороший кряк.
Проводим первичный обзор и выдаем на-гора пачку ссылок:
В первую очередь, надо использовать все возможные штатные средства. gcc предоставляет следующие интересные ключи, связанные с повышением бдительности компилятора и препроцессора.
Разумеется, не сам такой умный, а прочитал всё вот в этой ман-статье про ключи, связанные с предупреждениями
Пожалуй, самая достойная из найденных программ.
Официальный сайт программы и её плагин для эклипсоидов. Распознает довольно много, находит следующие ошибки:
Есть возможность помечать классы как умные указатели (чтобы не рапортовало о ложных мемликах), GUI на Qt4.
Vera++, в отличие от cppcheck, ориентированна на проверку стиля. Имеет пополняемую базу правил. По умолчанию в базе много реально идиотстких штук типа «перед двоеточием должен быть пробел». Единственная полезная возможность — запрет на использование using namespace в заголовочных файлах. Правила, однако можно писать и самому на языке Tcl. :)
RATS рассказывает довольно-таки убедительные страшилки про безопасность и buffer overflow-атаки. Не стал пристально разглядывать потому что не очень-то много знаю про защищенный код.
Удивительно, но программисты на чистом Си, похоже, больше заботятся о статическом анализе. Тут мы имеем список раз и два
Будут ли они полезны плюсовым разработчикам? Если у вас есть код без классов и вы помните, какие программы на C++ не будут собираться компилятором С, то почему бы и нет?
Вот такая штука для чистого C. Собирается практически без усилий, но работает чистенько и много чего ищет — смотри мануал.
Simian — similarity analyzer. Ищет дублирование кода, значит. Честно говоря, я не придумал ей применения
CIL — С Intermediate Language. Компилирует C в упрощенный C! Упрощенный C уже можно скармливать другим анализаторам, что теоретически должно повышать качество их работы.
А мало его такого. Много анализаторов, стоящих много долларов и не имеют кряков.
Вот пример такого анализатора, можно зайти на их сайт и попросить триальник Cleanscape. Возможности не сильно отличаются от cppcheck.
Не все ошибки в коде, поддающиеся статическому анализу, были представлены в существующих программах. А хотелось бы:
Плата за это соответствующая — не всегда вразумительные ошибки компилятора (попробуйте забыть поставить точку с запятой после определения класса), очень большой срок подготовки и обучения программистов, но самое главное — некоторые баги становятся заметными только во время исполнения программы.
Мы хотим больше полезных ворнингов до запуска наших программ. Одно из средств получения желаемого — статический анализ кода. Статический — значит, не запуская программу. Интересны не только вероятные ошибки, случаи undefined behaviour, утечки памяти, но и вещи вроде недоступности/неиспользуемости кода, рекомендации по повышению интуитивности стиля программирования.
Средства получения метрик ПО, добываемых методами статического анализа в этой статье не рассматриваются. Замечания, связанные со стандартами программирования (фигурная скобочка должна находиться на отдельной строчке, ууууу!!) тоже не интересны.
Критерии оценки простые — количество и полезность находимых багов, простота использования (в частности, отсутствие требований модификации кода), бесплатность/разумная цена/хороший кряк.
Проводим первичный обзор и выдаем на-гора пачку ссылок:
- Static_code_analysis
- Wikipedia
- Статья Скотта Мейерса об анализаторах
- тема на Stack overflow о бесплатных анализаторах
Найденные штуки
Педантичные ключи gcc
В первую очередь, надо использовать все возможные штатные средства. gcc предоставляет следующие интересные ключи, связанные с повышением бдительности компилятора и препроцессора.
- -Wall включает все ворнинги, среди которых совместимость с новым стандартом, границы массива (по-моему, не пашет, хотя говорят, что будет работать с -O2), volatile/register переменные (сообщит, что ему пофигу на твои умные слова и что //register//, а что нет, он будет решать сам), точки следования (i++ + ++i)
- -Wextra — еще пачка ворнингов типа пустых тел в if'ах, сравнение signed и unsigned
- -pedantic — следование ISO C++ стандарту. Например, запрет типа long long.
- -Weffc++ must have опция. Не включается с помощью -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 без параметров
- -Wconversion -Wsign-conversion — ворнинг о преобразовании типа. при котором значение может измениться. Как ни странно, не входит в -Wall
- -Winit-self — int i = i;
- -Wunreachable-code — код, который никогда не будет выполнен
Разумеется, не сам такой умный, а прочитал всё вот в этой ман-статье про ключи, связанные с предупреждениями
Cppcheck
Пожалуй, самая достойная из найденных программ.
Официальный сайт программы и её плагин для эклипсоидов. Распознает довольно много, находит следующие ошибки:
- некоторые memory leaks, например, отсутствие delete и delete[], отсутствие delete в деструкторе
- выход за границу массива
- exception'ы, бросаемые в деструкторе
- разыменование нулевого указателя
- разыменование после очистки памяти
- виртуальность деструктора базового класса
- использование одного и того же итератора для разных контейнеров
- разные более мелкие штуки
Есть возможность помечать классы как умные указатели (чтобы не рапортовало о ложных мемликах), GUI на Qt4.
Vera++
Vera++, в отличие от cppcheck, ориентированна на проверку стиля. Имеет пополняемую базу правил. По умолчанию в базе много реально идиотстких штук типа «перед двоеточием должен быть пробел». Единственная полезная возможность — запрет на использование using namespace в заголовочных файлах. Правила, однако можно писать и самому на языке Tcl. :)
RATS
RATS рассказывает довольно-таки убедительные страшилки про безопасность и buffer overflow-атаки. Не стал пристально разглядывать потому что не очень-то много знаю про защищенный код.
Проверялки для C без плюсов
Удивительно, но программисты на чистом Си, похоже, больше заботятся о статическом анализе. Тут мы имеем список раз и два
Будут ли они полезны плюсовым разработчикам? Если у вас есть код без классов и вы помните, какие программы на C++ не будут собираться компилятором С, то почему бы и нет?
Splint
Вот такая штука для чистого C. Собирается практически без усилий, но работает чистенько и много чего ищет — смотри мануал.
Simian
Simian — similarity analyzer. Ищет дублирование кода, значит. Честно говоря, я не придумал ей применения
CIL
CIL — С Intermediate Language. Компилирует C в упрощенный C! Упрощенный C уже можно скармливать другим анализаторам, что теоретически должно повышать качество их работы.
Непонятное, офтопное
- Oink. Будьте осторожны, если захотите это юзать. При компиляции мне показалось, что я собираю как минимум ядро linux для какой-нибудь экзотической архитектуры. требует Flex и Bison, долго догадывался… (: А еще надо фиксить кучу ошибок при компиляции — такое впечатление, что разработчики свое детище не то, что никогда не запускают — не собирали ни разу. В конце концов зверя одолел, а вот | список фич оказался отнюдь не внушительным. Работает с файлами препроцессора, но выдает по ним какую-то чушь: натравив на простую ошибку с границей массива — получаю тишину. Если же скормить oink'у что-нибудь на C++ с STL — он разразится тирадой на много-много строк. И это я получил ценой 3 часов компиляния и правки исходников?
- Mozilla Dehydra — нечто, базируещееся на этом самом Oink'е. Буду рад, если кто-нибудь расскажет об этой чекалке, ибо слово Mozilla в этот раз отнюдь не означало «все просто и понятно». Список находимых багов не увидел, компилять не хотелось после Oink'a.
- Еще есть компиляторы, которые предоставляют больше ворнингов на основе статического анализа. Например Rose
- Rational Purify — прославленная компания IBM Rational имеет свой набор инструментов для статического и динамического анализа. Буду рад, если кто-нибудь расскажем об этой программе, триальник для линукса у них оказался только для x64-архитектуры.
Триальное/крякнутое ПО
А мало его такого. Много анализаторов, стоящих много долларов и не имеют кряков.
Вот пример такого анализатора, можно зайти на их сайт и попросить триальник Cleanscape. Возможности не сильно отличаются от cppcheck.
Что бы еще хотелось
Не все ошибки в коде, поддающиеся статическому анализу, были представлены в существующих программах. А хотелось бы:
- Политику спецификации исключений как в Java.
- использование auto_ptr в контейнерах STL, разыменование auto_ptr после присвоения другому auto_ptr.
- using namespace в h-файлах
- переопределенный delete без new или new без delete
- вызов delete[] для немассивов
- использование vector с bool-значениями внутри