SlideShare una empresa de Scribd logo
1 de 26
Статический анализ кода: современный взгляд Карпов Андрей Николаевич к.ф.-м.н., технический директор ООО «Системы программной верификации» E-mail: karpov@viva64.com Program Verification Systems
О чем доклад? Андрей Карпов – сотрудник ООО «СиПроВер», разработчик статического анализатора кода PVS-Studio; доклад посвящен состоянию дел в области статического анализа Си/Си++ кода; это не сравнение инструментов, а взгляд на развитие отрасли.
Статический анализ это просмотр исходного кода разработчиком в тех местах, где по мнению статического анализатора присутствует неверное оформление или ошибка.
Два основных направления статического анализа Часто «дискредитируют» статический анализ.
Устаревают стандарты кодирования А все что не развивается, то умирает среды разработки подсказывают тип переменных, раскрашивают код, помогают в его форматировании; компиляторы выдают все больше предупреждений; язык развивается, появляются новые технологии программирования; многие правила уже не актуальны.
Классическое. Не используйте комментарии в стиле C: /* … */ Стандарт MISRA предостерегает от использования комментариев в стиле /* … */. Комментарии плохо заметны. Сложнее разобраться в коде, легче допустить ошибку.  Вернее были плохо заметны.  Не актуально
Есть просто устаревшее А вот еще одна из рекомендаций MISRA, реализованная в Parasoft C++test: (misra-008) Do not use wide string literals Не используйте строки в формате wchar_t. Не рекомендуется: wchar_t* x = L"Fred"; //нарушение Пора рекомендовать наоборот! Рекомендуется: char* x = "Fred";
Привет из 1992 года… В Pasrasoft C++test присутствует правило, взятое из стандарта кодирования 1992 года: (ellemtel_rule-01) Include files in C++ always have the file name extension ".hh". В С++файлах должны использоваться заголовочные файлы с расширением ".hh". Не сказал бы, что это повсеместно прижилось… Не рекомендуется: #include "MyClass.h" // нарушение Не интересно Рекомендуется: #include "MyClass.hh"
С некоторыми правилами не поспоришь - но толку от них никакого Pasrasoft C++test: (ellemtel_rule-37) Do not use 'magic numbers‘ Не используйте магические числа. Вообще не используйте! Делайте enumили константы. Не рекомендуется: float rgb[3]; // нарушение n = sizeof(rgb) / sizeof(rgb[0]) // нарушение Рекомендуется: const size_t RgbArraySize = 3; float rgb[RgbArraySize]; enumcolor { RED = 0, BLUE = 1, GREEN = 2 }; n = sizeof(rgb) / sizeof(rgb[RED]); Формально все верно. Но нерациональные трудозатраты при сомнительной пользе.
Опасно использовать адресную арифметику - не поспоришь В С++Test имеется проверка относящаяся к MISRA: (misra-101)Do not use pointer arithmetic. Не используйте адресную арифметику.  Не рекомендуется: int* p; p++; // нарушение int *x = p+5; // нарушение Спасибо за рекомендацию. А что мне с ней делать? Рекомендуется: не использовать 
Поиск ошибок тоже устаревает ошибки все лучше выявляются компилятором; многим разработчикам уже не интересны ошибки, связанные с FAR указателями или массивами больше 64-килобайт; мало внимания уделяется использованию библиотек (stl, boost, MFC, Windows API).
Хорошее, но устаревшее правило для диагностики Неправильно: class ClassX {  …ClassX(const ClassXx) { m_v = x.m_v; } // нарушение }; При вывозе конструктора копирования возникнет вечный цикл. Правильно: class ClassX {  …ClassX(const ClassX&x) { m_v = x.m_v; }};
Давно реализовано в Visual C++.Даже не компилируется ClassX(const ClassXx) { m_v = x.m_v; } VS2005 сообщает: error C2652: 'ClassX' : illegal copy constructor: first parameter must not be a 'ClassX‘ Хорошо, что это правило №1063 есть и в PC-Lint. На свете еще много неполноценных компиляторов для микроконтроллеров.  Но разработчику, использующему Visual Studio 2005/2008/2010 это уже не интересно.
Пример хорошей проверки PC-Lint: №682 В примере «array» является указателем , а не массивом.  В 32-битной программе получим значение 1, а не 3. Неправильно: void Foo26(float array[3]) { size_t n = sizeof(array) / sizeof(array[0]); //нарушение Правильно: void Foo26(float *array, size_t array_size) { size_t n = array_size;
Пример хорошей проверки Parasoft C++test: sa-100_DoNotTreatArraysPolymorphically class Class5_Base { int a; }; class Class5 : public Class5_Base { int b; }; void Process5(Class5_Base *p, size_t n) {   for (size_t i = 0; i != n; ++i)     p[i].a = 22; } Class5 X[5]; Process5(X, 5); //нарушение Через указатель на базовый класс нельзя работать с массивом производных классов, таккак классы имеют разный размер.
Пример хорошей проверки PVS-Studio: V512: A call of the 'memset' function will lead to a buffer overflow or underflow. Неправильно: MD5Context *ctx; ... memset(ctx, 0, sizeof(ctx)); // нарушение if (memcmp(this, &other, sizeof(Matrix4) == 0)) // нарушение Правильно: MD5Context *ctx; ... memset(ctx, 0, sizeof(*ctx)); if (memcmp(this, &other, sizeof(Matrix4)) == 0)
Пример хорошей проверки PC-Lint: №1546. Нельзя бросать исключение из деструктора.  ~ClassX()   {     if (!m_init)       throw std::exception("Error"); //нарушение     free(m_p1);     free(m_p2);   }
Пример хорошей проверки Parasoft C++test: ecpp-25_ZeroConversionProblem void func(float, int *) { } void func(float, int) { } void F()  { Неправильно: func(1.0f, 0); //нарушение func(1.0f, NULL); //нарушение Правильно: func(1.0f, nullptr); } Неожиданное поведение кода из-за выбора не той перегруженной функции.
Пример хорошей проверки PVS-Studio: V501. There are identical sub-expressions to the left and to the right of the '||' operator. Слева и справа от оператора ||, &&, ==, <=, … находятся одинаковые подвыражения, не имеющие побочных эффектов. Неправильно: class Foo { intiChilds[2];   ... boolhasChilds() const { return(iChilds > 0 || iChilds > 0); } // нарушение } Правильно: boolhasChilds() const { return(iChilds[0] > 0 || iChilds[1] > 0); }
Пример хорошей проверки Code Analysis for C/C++: Неправильно: HRESULT hr = CoInitialize(NULL);  if (!hr) //нарушение C6217: неявное приведение между семантически различными целочисленными типами: проверка HRESULT с "not". Правильно: if (FAILED(hr)) C6225: неявное приведение между семантически различными целочисленными типами: присвоение HRESULT значения 1 или TRUE. Неправильно: HRESULThr; hr = TRUE; //нарушение Правильно: #define S_OK ((HRESULT)0L) hr = S_OK;
Сам придумалНигде аналогичной проверки не видел PVS-Studio: V517. The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Неправильно: if(radius < THRESH * 5) *yOut = THRESH * 10 / radius; else if (radius < THRESH * 5) //нарушение *yOut = -3.0f / (THRESH * 5.0f) * (radius - THRESH * 5.0f) + 3.0f; else   *yOut = 0.0f; Повторяющиеся условия в конструкции вида "else if". Правильно: Затрудняюсь привести верный вариант.
Состояние дел в области статического анализа Многое из нового делается «для галочки»: Qt Best Practices Rules; /Wp64 в Visual C++ – это 10%-15% от того, что позволяет обнаружить Viva64. Хромает поддержка нового и C++0x в частности.
Состояние дел в области статического анализа Gimpel PC-Lint; Parasoft C++test; Coverity; Klocwork; Visual Studio: Code Analysis for C/C++; PVS-Studio.
PVS-Studio: Viva64 – выявление 64-битных ошибок; VivaMP - выявление параллельных ошибок; в разработке современный статический анализатор общего назначения. Скачать PVS-Studio: http://www.viva64.com/ru/pvs-studio/download/
Выводы многие правила статических анализаторов безнадежно устарели; если в новой версии анализатора меняется только интерфейс программы, но не правила анализа, то продукт перестает быть актуальным; но развитие языка и библиотек всегда сохраняет актуальность статического анализа; самые крутые компиляторы проигрывают самым крутым инструментам анализа.
Вопросы? Контактная информация: Карпов Андрей Николаевич к.ф.-м.н., технический директор ООО «Системы программной верификации» Сайт: http://www.viva64.com/ru/main/ E-mail: karpov@viva64.com Тел.: +7 (4872) 38-59-95 (GMT + 03:00) Twitter: https://twitter.com/Code_Analysis

Más contenido relacionado

La actualidad más candente

Basics of assertions in automated testing
Basics of assertions in automated testingBasics of assertions in automated testing
Basics of assertions in automated testing
Þorgeir Ingvarsson
 
20120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture0420120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture04
Computer Science Club
 
How to Calculate Test Automation ROI
How to Calculate Test Automation ROIHow to Calculate Test Automation ROI
How to Calculate Test Automation ROI
Þorgeir Ingvarsson
 
White box techniques
White box techniquesWhite box techniques
White box techniques
QA Guards
 
апкс 2011 04_verilog
апкс 2011 04_verilogапкс 2011 04_verilog
апкс 2011 04_verilog
Irina Hahanova
 
паскаль. часть1
паскаль. часть1паскаль. часть1
паскаль. часть1
igorm9so
 

La actualidad más candente (20)

Basics of assertions in automated testing
Basics of assertions in automated testingBasics of assertions in automated testing
Basics of assertions in automated testing
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
 
20120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture0420120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture04
 
Обработка ошибок — общие соображения и грязные подробности
Обработка ошибок — общие соображения и грязные подробностиОбработка ошибок — общие соображения и грязные подробности
Обработка ошибок — общие соображения и грязные подробности
 
How to Calculate Test Automation ROI
How to Calculate Test Automation ROIHow to Calculate Test Automation ROI
How to Calculate Test Automation ROI
 
WTF Code @ jug.lv
WTF Code @ jug.lvWTF Code @ jug.lv
WTF Code @ jug.lv
 
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМПрограммирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
 
паскаль
паскальпаскаль
паскаль
 
White box techniques
White box techniquesWhite box techniques
White box techniques
 
Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.
 
практические советы по улучшению качества кода
практические советы по улучшению качества кодапрактические советы по улучшению качества кода
практические советы по улучшению качества кода
 
апкс 2011 04_verilog
апкс 2011 04_verilogапкс 2011 04_verilog
апкс 2011 04_verilog
 
Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?
 
паскаль. часть1
паскаль. часть1паскаль. часть1
паскаль. часть1
 
Golang WTF talks
Golang WTF talksGolang WTF talks
Golang WTF talks
 
50 оттенков красного
50 оттенков красного50 оттенков красного
50 оттенков красного
 
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
 

Destacado

Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
Andrey Karpov
 

Destacado (6)

Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
 
Статический анализ Си++ кода и новый стандарт языка C++0x
Статический анализ Си++ кода и новый стандарт языка C++0xСтатический анализ Си++ кода и новый стандарт языка C++0x
Статический анализ Си++ кода и новый стандарт языка C++0x
 
Что нового в Visual Studio 2013
Что нового в Visual Studio 2013Что нового в Visual Studio 2013
Что нового в Visual Studio 2013
 
Программа для регрессионного тестирования анализаторов PVS-Studio, CppCat
Программа для регрессионного тестирования анализаторов PVS-Studio, CppCatПрограмма для регрессионного тестирования анализаторов PVS-Studio, CppCat
Программа для регрессионного тестирования анализаторов PVS-Studio, CppCat
 
PVS-Studio static analyzer: advanced features
PVS-Studio static analyzer: advanced featuresPVS-Studio static analyzer: advanced features
PVS-Studio static analyzer: advanced features
 
Static code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0xStatic code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0x
 

Similar a Статический анализ кода: современный взгляд

Что могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщикиЧто могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщики
Andrey Karpov
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
corehard_by
 
Тестирование весна 2013 лекция 2
Тестирование весна 2013 лекция 2Тестирование весна 2013 лекция 2
Тестирование весна 2013 лекция 2
Technopark
 
SAST, борьба с потенциальными уязвимостями
SAST, борьба с потенциальными уязвимостямиSAST, борьба с потенциальными уязвимостями
SAST, борьба с потенциальными уязвимостями
Andrey Karpov
 

Similar a Статический анализ кода: современный взгляд (20)

PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
PVS-Studio vs Chromium
PVS-Studio vs ChromiumPVS-Studio vs Chromium
PVS-Studio vs Chromium
 
Что могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщикиЧто могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщики
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
 
About Python
About PythonAbout Python
About Python
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Тестирование весна 2013 лекция 2
Тестирование весна 2013 лекция 2Тестирование весна 2013 лекция 2
Тестирование весна 2013 лекция 2
 
SAST, борьба с потенциальными уязвимостями
SAST, борьба с потенциальными уязвимостямиSAST, борьба с потенциальными уязвимостями
SAST, борьба с потенциальными уязвимостями
 
Статический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокСтатический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибок
 
Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...Улучшение качества открытого программного обеспечения с помощью инструментов ...
Улучшение качества открытого программного обеспечения с помощью инструментов ...
 
C++/CLI Now Supported in PVS-Studio and CppCat
C++/CLI Now Supported in PVS-Studio and CppCatC++/CLI Now Supported in PVS-Studio and CppCat
C++/CLI Now Supported in PVS-Studio and CppCat
 

Más de Andrey Karpov

Más de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Статический анализ кода: современный взгляд

  • 1. Статический анализ кода: современный взгляд Карпов Андрей Николаевич к.ф.-м.н., технический директор ООО «Системы программной верификации» E-mail: karpov@viva64.com Program Verification Systems
  • 2. О чем доклад? Андрей Карпов – сотрудник ООО «СиПроВер», разработчик статического анализатора кода PVS-Studio; доклад посвящен состоянию дел в области статического анализа Си/Си++ кода; это не сравнение инструментов, а взгляд на развитие отрасли.
  • 3. Статический анализ это просмотр исходного кода разработчиком в тех местах, где по мнению статического анализатора присутствует неверное оформление или ошибка.
  • 4. Два основных направления статического анализа Часто «дискредитируют» статический анализ.
  • 5. Устаревают стандарты кодирования А все что не развивается, то умирает среды разработки подсказывают тип переменных, раскрашивают код, помогают в его форматировании; компиляторы выдают все больше предупреждений; язык развивается, появляются новые технологии программирования; многие правила уже не актуальны.
  • 6. Классическое. Не используйте комментарии в стиле C: /* … */ Стандарт MISRA предостерегает от использования комментариев в стиле /* … */. Комментарии плохо заметны. Сложнее разобраться в коде, легче допустить ошибку. Вернее были плохо заметны. Не актуально
  • 7. Есть просто устаревшее А вот еще одна из рекомендаций MISRA, реализованная в Parasoft C++test: (misra-008) Do not use wide string literals Не используйте строки в формате wchar_t. Не рекомендуется: wchar_t* x = L"Fred"; //нарушение Пора рекомендовать наоборот! Рекомендуется: char* x = "Fred";
  • 8. Привет из 1992 года… В Pasrasoft C++test присутствует правило, взятое из стандарта кодирования 1992 года: (ellemtel_rule-01) Include files in C++ always have the file name extension ".hh". В С++файлах должны использоваться заголовочные файлы с расширением ".hh". Не сказал бы, что это повсеместно прижилось… Не рекомендуется: #include "MyClass.h" // нарушение Не интересно Рекомендуется: #include "MyClass.hh"
  • 9. С некоторыми правилами не поспоришь - но толку от них никакого Pasrasoft C++test: (ellemtel_rule-37) Do not use 'magic numbers‘ Не используйте магические числа. Вообще не используйте! Делайте enumили константы. Не рекомендуется: float rgb[3]; // нарушение n = sizeof(rgb) / sizeof(rgb[0]) // нарушение Рекомендуется: const size_t RgbArraySize = 3; float rgb[RgbArraySize]; enumcolor { RED = 0, BLUE = 1, GREEN = 2 }; n = sizeof(rgb) / sizeof(rgb[RED]); Формально все верно. Но нерациональные трудозатраты при сомнительной пользе.
  • 10. Опасно использовать адресную арифметику - не поспоришь В С++Test имеется проверка относящаяся к MISRA: (misra-101)Do not use pointer arithmetic. Не используйте адресную арифметику. Не рекомендуется: int* p; p++; // нарушение int *x = p+5; // нарушение Спасибо за рекомендацию. А что мне с ней делать? Рекомендуется: не использовать 
  • 11. Поиск ошибок тоже устаревает ошибки все лучше выявляются компилятором; многим разработчикам уже не интересны ошибки, связанные с FAR указателями или массивами больше 64-килобайт; мало внимания уделяется использованию библиотек (stl, boost, MFC, Windows API).
  • 12. Хорошее, но устаревшее правило для диагностики Неправильно: class ClassX { …ClassX(const ClassXx) { m_v = x.m_v; } // нарушение }; При вывозе конструктора копирования возникнет вечный цикл. Правильно: class ClassX { …ClassX(const ClassX&x) { m_v = x.m_v; }};
  • 13. Давно реализовано в Visual C++.Даже не компилируется ClassX(const ClassXx) { m_v = x.m_v; } VS2005 сообщает: error C2652: 'ClassX' : illegal copy constructor: first parameter must not be a 'ClassX‘ Хорошо, что это правило №1063 есть и в PC-Lint. На свете еще много неполноценных компиляторов для микроконтроллеров. Но разработчику, использующему Visual Studio 2005/2008/2010 это уже не интересно.
  • 14. Пример хорошей проверки PC-Lint: №682 В примере «array» является указателем , а не массивом. В 32-битной программе получим значение 1, а не 3. Неправильно: void Foo26(float array[3]) { size_t n = sizeof(array) / sizeof(array[0]); //нарушение Правильно: void Foo26(float *array, size_t array_size) { size_t n = array_size;
  • 15. Пример хорошей проверки Parasoft C++test: sa-100_DoNotTreatArraysPolymorphically class Class5_Base { int a; }; class Class5 : public Class5_Base { int b; }; void Process5(Class5_Base *p, size_t n) { for (size_t i = 0; i != n; ++i) p[i].a = 22; } Class5 X[5]; Process5(X, 5); //нарушение Через указатель на базовый класс нельзя работать с массивом производных классов, таккак классы имеют разный размер.
  • 16. Пример хорошей проверки PVS-Studio: V512: A call of the 'memset' function will lead to a buffer overflow or underflow. Неправильно: MD5Context *ctx; ... memset(ctx, 0, sizeof(ctx)); // нарушение if (memcmp(this, &other, sizeof(Matrix4) == 0)) // нарушение Правильно: MD5Context *ctx; ... memset(ctx, 0, sizeof(*ctx)); if (memcmp(this, &other, sizeof(Matrix4)) == 0)
  • 17. Пример хорошей проверки PC-Lint: №1546. Нельзя бросать исключение из деструктора. ~ClassX() { if (!m_init) throw std::exception("Error"); //нарушение free(m_p1); free(m_p2); }
  • 18. Пример хорошей проверки Parasoft C++test: ecpp-25_ZeroConversionProblem void func(float, int *) { } void func(float, int) { } void F() { Неправильно: func(1.0f, 0); //нарушение func(1.0f, NULL); //нарушение Правильно: func(1.0f, nullptr); } Неожиданное поведение кода из-за выбора не той перегруженной функции.
  • 19. Пример хорошей проверки PVS-Studio: V501. There are identical sub-expressions to the left and to the right of the '||' operator. Слева и справа от оператора ||, &&, ==, <=, … находятся одинаковые подвыражения, не имеющие побочных эффектов. Неправильно: class Foo { intiChilds[2]; ... boolhasChilds() const { return(iChilds > 0 || iChilds > 0); } // нарушение } Правильно: boolhasChilds() const { return(iChilds[0] > 0 || iChilds[1] > 0); }
  • 20. Пример хорошей проверки Code Analysis for C/C++: Неправильно: HRESULT hr = CoInitialize(NULL); if (!hr) //нарушение C6217: неявное приведение между семантически различными целочисленными типами: проверка HRESULT с "not". Правильно: if (FAILED(hr)) C6225: неявное приведение между семантически различными целочисленными типами: присвоение HRESULT значения 1 или TRUE. Неправильно: HRESULThr; hr = TRUE; //нарушение Правильно: #define S_OK ((HRESULT)0L) hr = S_OK;
  • 21. Сам придумалНигде аналогичной проверки не видел PVS-Studio: V517. The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Неправильно: if(radius < THRESH * 5) *yOut = THRESH * 10 / radius; else if (radius < THRESH * 5) //нарушение *yOut = -3.0f / (THRESH * 5.0f) * (radius - THRESH * 5.0f) + 3.0f; else *yOut = 0.0f; Повторяющиеся условия в конструкции вида "else if". Правильно: Затрудняюсь привести верный вариант.
  • 22. Состояние дел в области статического анализа Многое из нового делается «для галочки»: Qt Best Practices Rules; /Wp64 в Visual C++ – это 10%-15% от того, что позволяет обнаружить Viva64. Хромает поддержка нового и C++0x в частности.
  • 23. Состояние дел в области статического анализа Gimpel PC-Lint; Parasoft C++test; Coverity; Klocwork; Visual Studio: Code Analysis for C/C++; PVS-Studio.
  • 24. PVS-Studio: Viva64 – выявление 64-битных ошибок; VivaMP - выявление параллельных ошибок; в разработке современный статический анализатор общего назначения. Скачать PVS-Studio: http://www.viva64.com/ru/pvs-studio/download/
  • 25. Выводы многие правила статических анализаторов безнадежно устарели; если в новой версии анализатора меняется только интерфейс программы, но не правила анализа, то продукт перестает быть актуальным; но развитие языка и библиотек всегда сохраняет актуальность статического анализа; самые крутые компиляторы проигрывают самым крутым инструментам анализа.
  • 26. Вопросы? Контактная информация: Карпов Андрей Николаевич к.ф.-м.н., технический директор ООО «Системы программной верификации» Сайт: http://www.viva64.com/ru/main/ E-mail: karpov@viva64.com Тел.: +7 (4872) 38-59-95 (GMT + 03:00) Twitter: https://twitter.com/Code_Analysis