Философия статического анализа кода: у нас 100 программистов, анализатор нашел мало ошибок, он бесполезен?

    Люди очень часто неправильно думают про статический анализ кода.

    Часто можно встретить такое мнение, выраженное в следующем абзаце:

    У нас большой проект. В нем работает несколько десятков (сотен) программистов. То есть тот самый, про который вы пишите, что нужен статический анализ. Я скачал анализатор кода, выполнил проверку и нашел очень мало ошибок. Очевидно, что анализатор кода просто бесполезен!

    Увы и ах, но, похоже, способ продвижения статического анализа кода через идею проверки open source проектов играет с людьми злую шутку. Люди ОЖИДАЮТ, что запустив анализатор на случайном проекте, они ОБЯЗАТЕЛЬНО найдут кучу ошибок. Конечно же это не так, и вот почему.

    Предположим, у нас есть проект, в котором участвует 10 программистов, 3 тестировщика и 1 руководитель проекта. Рассмотрим временной интервал в один месяц (21 рабочий день). Интервал выбран произвольно и на самом деле не важен.

    Пусть в первый рабочий день программисты писали код и внесли в него 5 ошибок. На следующий день тестировщики нашли эти 5 ошибок и отписали программистам. На третий день программисты исправили 5 ошибок. Вот у нас образовалась такая «тройка» или когорта: один день делаем ошибки, второй день находим, в третий – исправляем.

    Очевидно, что эта когорта движется во времени, и каждый день ошибки добавляются, обнаруживаются и исправляются. Хотя в каждый момент времени активно не так уж много ошибок, но «окно» движется и общее количество проделанной работы по выявлению и исправлению ошибок довольно существенно. В последний день 21-дневного рабочего цикла руководителю проекта это надоело, он наорал на всех и все ошибки были исправлены. В результате, в конце месяца, в проекте 0 ошибок. Это, конечно, продлится недолго, но начальник рад красивому итогу месяца.

    Предположим, в этот 21-й день кто-то из программистов скачал анализатор кода, выполнил проверку, получил 0 ошибок по делу (и парочку бестолковых срабатываний) и делает, на первый взгляд, очевидный, но неверный вывод: анализаторы кода просто не работают и не нужны!

    Теперь рассмотрим движение нашей когорты в случае, если анализатор кода используется регулярно.

    В первый день программисты также допустили 5 ошибок. Но благодаря автоматическому анализу кода, 3 ошибки были сразу найдены и исправлены ещё на этапе кодирования. Поэтому, на следующий день, тестировщики найдут всего 2 ошибки. На третий день программистам будет намного меньше работы по правкам, так как часть ошибок была исправлена ещё в первый день. Получается, что анализатор сократил количество работы по устранению ошибок более чем в два раза, что существенно ускоряет процесс разработки проекта в целом.

    Конечно, числа выше были приведены условно. Самое главное, что можно сделать правильный важный вывод. Статический анализ наиболее полезен не как разовое действие, а как регулярный процесс.
    PVS-Studio 207,38
    Ищем ошибки в C, C++ и C# на Windows и Linux
    Поделиться публикацией
    Похожие публикации
    Комментарии 26
    • –2

      А что, отец, люди которые даже бесплатные статические анализаторы не используют в вашем городе есть? Тот же clang-check от совсем глупых ошибок вроде неплохо спасает.

      • +3
        У нас 100 пожарных, и не одного пожара. Что мы делаем не так?
        • 0
          Непонятная какая-то аналогия.
          • +1
            Вы всё делаете так. Если эти пожарные регулярно объезжают город и в пожароопасных местах наводят порядок — то и хорошо. Пожарные для того и нужны, чтобы пожаров меньше было, с не чтобы с ними «героически бороться», когда уже всё полыхает…
            • +1
              Если у вас нет пожаров, зачем вам пожарные?
              • 0

                Здесь пожарные подразумеваются как отрасль. Т.е. конкретная служба с проверками занимается противопожарной безопасностью. Если их убрать, все быстро поменяется. Только еще плюс ко всему, тушить будет некому. Лучше пусть будет кем тушить, но нечего.

              • 0
                Вспоминая Жеглова: «А ты скажи ему, что правопорядок в стране определяется не наличием воров, а умением властей их обезвреживать. Вот так»
              • +2
                Хочу заметить, что такой анализатор не спасет от логических ошибок в бизнес-логике приложения. Тут помогут только юнит тесты. Но эти же самые тесты выявят любые ошибки, в том числе и те, что обнаруживает статический анализатор. Кроме того, анализатор не поможет, если часть логики находится, например, в хранимых процедурах на уровне БД.
                • +5
                  Хочу заметить, что такой анализатор не спасет от логических ошибок в бизнес-логике приложения. Тут помогут только юнит тесты.
                  Про бизнес логику Вы правы.

                  Но эти же самые тесты выявят любые ошибки, в том числе и те, что обнаруживает статический анализатор.
                  А вот здесь дело обстоит иначе. Теоретически утверждение верно, но к практике оно не применимо.
                  Статические анализаторы и юнит-тесты не конкурируют, а дополняют другую. У юнит-тестов есть слабые места, которые отлично подстрахует статический анализ:

                  • Сами юнит-тесты часто содержат ошибку. Для юнит-тестов не пишут другие юнит-тесты. :) Зато анализатор проверяет тесты. И по моему опыту, там очень часто находятся ошибки. Чаще всего выясняется, что тест ничего не тестирует.
                  • Не все ошибки можно найти юнит-тестами. Вернее, это слишком сложно. Например, юнит тестом очень сложно найти ошибку обнуления стековой памяти при выходе из функции. Я имею в виду вот это. Или, например, юнит-тестом можно не найти чтение из неинициализированной переменной (тестам повезёт и там будет хорошее значение).
                  • Слишком дорого покрыть тестами весь код. Статические анализаторы проверяют весь код. В результате, находится огромное количество ошибок в коде, который редко выполняется.
                  • Непонятно что делать с большим проектом, в котором мало юнит-тестов, а хочется в обозримом времени улучшить его качество. Писать тесты — слишком долго и дорого. Статический анализ в этот момент становится хорошей альтернативой.


                  • +5
                    Прочитал и чуть завыть не захотелось!
                    Живу я в аскетичном мире golang и об анализаторах кода в нем речи нет и, видимо, не будет. Так вот даже обилие тестов не заменит анализатор — это подходы с разных сторон для обеспечения качества кода и сокращения расходов.
                    • 0
                      эм, как бы есть встроенный vet много чего может подсказать по коду, понятно что в go нет pointer арифметики, а за память у него gc отвечает, но это не значит что в какой ни буть  printf программист передал все аргументы да ещё и правильных типов и т.п.
                      • 0
                        К сажалению, это на уровне code style масимум. Ошибки практически не отлавливаются, даже те, которые можно отлавливать: утекшие горутины из-за блокировки канала, классические ошибки из списка 50 оттенков go.
                    • 0
                      Для юнит-тестов не пишут другие юнит-тесты.

                      Не совсем, есть же мутационное тестирование, которое как-раз выявляет качество тестов, wiki:


                      Mutation testing (or Mutation analysis or Program mutation) is used to design new software tests and evaluate the quality of existing software tests
                      • 0
                        А ещё тестами довольно сложно проверять многопоточность.
                      • 0
                        Тогда уж сильные системы типов, позволяющие специфицировать предметную модель в непосредственно типе.
                        • 0
                          Юнит тест будет содержать ту же логическую ошибку.
                        • 0
                          Да только проблема не в том, что анализатор не найдет ошибок, а в том что выдаст миллион ложных срабатываний. Единственный вариант использовать его с самых первых строк нового проекта. А они есть вообще на C++?
                          • 0
                            Да только проблема не в том, что анализатор не найдет ошибок, а в том что выдаст миллион ложных срабатываний.
                            Вы преувеличиваете размер беды. Да, поначалу анализаторы кода могут выдавать огромное количество предупреждений. Однако, все серьёзные анализаторы кода предоставляют различные варианты настройки. И уже после минимальной настройки, количество ложных срабатываний может быть уменьшено в разы. Больше всего ложных срабатываний относится к неудачным макросам. Разметив эти макросы, можно получить сразу намного более приятную картину в отчёте.

                            Например, вот статья где идёт речь о количестве ложных срабатываний, выдаваемых PVS-Studio: Характеристики анализатора PVS-Studio на примере EFL Core Libraries, 10-15% ложных срабатываний.

                            Единственный вариант использовать его с самых первых строк нового проекта.
                            Да, это вполне вариант. Но почти нереальный на практике. :)

                            Поэтому в PVS-Studio есть вариант разметить все предупреждения как пока неинтересные и работать только с предупреждениями, относящимися к новому или изменённому коду. Это позволяет легко внедрить использование статического анализа в большой проект и начать сразу получать от него пользу. Подробнее: Массовое подавление сообщений анализатора (отключение выдачи предупреждений на существующий код).
                            • 0
                              Если у вас в проекте «миллион ложных срабатываний», то видимо это не очень качественный проект.
                              • 0
                                Я вам больше скажу — это ужасный проект. Это проект, который разрабатывался сотней человек последние 15 лет. Он содержит 4G исходников. Он собирается за 2.5 часа. Там нельзя включить максимальный кровень предупреждений поскольку слетает Visual Studio. Там много еще всякого.

                                Но… только такие проекты и имеют ценность.

                                Так что миллион ложных срабатываний — это не перувеличение. Это данность. И размечать неинтересные предупреждения статического анализатора — тоже не вариант. Помогает только отключение всего и включение только интересных, что убивает саму идею анализатора.

                                За всю историю моих мытарств с анализом кодовой базы я нашел только 1 (один) инструмент, который успешло распарсил все исходники (и разумеется я забыл его название :) ). Все кроссреференсеры, инструментирующие профайлеры, тулы типа парсера кода от Rational Rose — все падают.
                                • +1
                                  Давайте заведем вместе на нем PVS-Studio?
                            • +2
                              Ну вот тут вы уже начинаете немного подвирать. Между программистами и «тестировщиком» находятся ещё автоматические тесты, которые и ловят большинство ошибок.

                              А вот если их нет, то польза от PVStudio будет никакая, потому что результирующий продукт всё равно будет страшно сырой, а тестировщики всё не оттестируют.
                              • –1
                                Давайте лучше это считать преувеличением, которое призвано выделить главную мысль. Мир вообще сложный и про него трудно говорить. Поэтому придумывают упрощенные модели, чтобы разобраться с каким-то вопросом и пояснить другим. :)
                              • 0
                                в тегах к статье вы указали «Java». Вопрос: когда можно будет проверить свой java проект вашим анализатором?
                                • 0
                                  Ну, когда-нибудь можно будет. :)
                                • +1
                                  хороший пример, много проверок не бывает, лучше запускать тесты и анализаторы каждый день над своим кодом, чем гдето там потом…

                                  у нас похожая ситуация была… программисты пишут-пишут, тестер проверяет, исправляют, проверяют, исправляют… а гдето бывает вылазят новые в ходе исправлений. ужас был. было время и без тестера — еще тот ад.

                                  ситуация качественно изменилась после внедрения тестов: фичу сделал, тесты запустил — все ок, ушло тестеру, который в очень редких случаях чтото находит :)

                                  жаль на Go не видел анализаторов подобных Вашему.

                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                  Самое читаемое