Pull to refresh
583
22
Андрей Карпов @Andrey2008

Директор по маркетингу

Send message
Документ навеял мысли повторить проверку Chromium :)
Проверка Chromium спустя три года. Ну и как оно?

специально для этого наглого гражданина напишу первую часть статьи, где все ваши мифы разрушу раз и навсегда. Заслужили, так заслужили.

Я так и не дождался этой обещанной статьи, поэтому написал собственную :)

Вызов виртуальных функций в конструкторах и деструкторах (C++)

Пока не изменилась. Использование машинного обучения в статическом анализе исходного кода программ.
Мы посмотрели на этот ControlFlag, думали может по него какую-то статью обзорную написать. Но там писать не про что. Для кода анализатора PVS-Studio (C++ ядро) выдал всего два бессмысленных сообщения вида:
template <typename F, std::enable_if_t<std::is_invocable_r_v<bool, F, const Ptree*> , int> = 0>
[[nodiscard]] bool FindIf(const Ptree* tree, F f)
{
  while (tree != nullptr)
  {
    if (f(tree))
      return true;
    if (tree->IsLeaf())
      return false;
    if (FindIf(tree->Car(), f)) 
      return true;              // <=
    tree = tree->Cdr();
  }
  
  return false;
}

Ему подозрительно, что 2 соседних if'а имеют return true, а посередине return false. Хм…

Для сравнения, от того-же ASan, на практике гораздо больше прока: Зачем нужен динамический анализ кода, на примере проекта PVS-Studio.

PVS-Studio не ориентируется на ФСТЭК. Svace ориентирован на ФСТЭК. Актуален ФСТЭК - берите Svace.

Подразумевается, что каждый подписанный на C \ С++ хаб, слышал про Cppcheck :)

Кстати, ещё одна интересная история сегодня про поддержку появилась: Слава баг-репортам, или как мы сократили время анализа проекта пользователя с 80 до 4 часов.
За основу возьмём реальное общение: больше 100 писем в переписке, исключения, анализ, который не завершается за трое суток…
Просто не получится :). Это ведь ещё и разные диагностики :). Изначально речь шла про V634. Она именно оценивает выражения со сдвигами.

Паттерн вида x << y + z.
Забывают, что у сложения/вычитания/умножения/деления более высокий приоритет, чем у сдвига. Лучше всегда явно ставить скобки.
Пример:
int x = a<<4 + b;

Исключения:
  1. Операция с высоким приоритетом находится в макросе, а сдвиг нет.
  2. Операция с высоким приоритетом ('-','/','%') выполняется над числом 64(int64), 32(int), 16(short), 8(char).
  3. Разделение на строки выражения свидетельствует о преднамеренном использовании:
     a = 1 <<
          2 * 8; //ok
     b = 2 
          << 2 * 8 //ok
     c = 3 << 2
              * 8 //err
    
  4. Нет смысл сдвигать вправо константу на константу или влево константу (кроме 1) на константу.
  5. Сдвиг является условием. В этом случае нет смысла результат сдвига умножать. Пример: if (value >> (i — 1) * 8)


А если речь заходит про && и ||, то это уже V648.

Странно, когда логические операции '&&' и '||' используются вместе и не разделены скобками. Часто их приоритеты путают. Приоритет оператора && выше, чем у ||.

Следует предупреждать в том случае, если написано так: A || B && C.
Исключение:
  1. Если имеется выражение вида A || !A && B, т.е. оператор || разделяет два противоположных по смыслу высказывания.
  2. Если выражение вида… || p != nullptr && f(p) ...
  3. Имеется выражение вида x == 0 || A != 123 && A != 321, т.е. оператор &&
    разделяет сравнение одной и той же переменной с разными константами.
    При этом, с одной стороны от последовательности || && ничего не должно быть.
       Т.е. здесь не ругаемся: b || A != 0 && A != 1
             а здесь ругаемся: b || A != 0 && A != 1 || c
             и здесь ругаемся: b || A != 0 && (A != 1 || c)
    

if (a && b || c && d) // нет
if (a || b && c || d) // да
x = 1 + 3 * y; // нет

  1. Первая строка. Тот, кто писал, скорее всего понимает, что хочет объединить операцией || два подвыражения. Типовой код. Ошибки скорее всего нет.
  2. Вторая строка. Возможно, код работает не так, как ожидает программист. Возможно, ошибки нет, но код лучше перепроверить.
  3. Третья строка. Невероятно, что кто-то спутает приоритет операций + и *. Ошибки скорее всего нет.
Анализатор отталкивается не от теоретических, а практических типов :). В данном режиме сборки int 32-битный. А значит может быть переполнение.
Не будет из 100500. Не верится, что такие выражения часто требуются. А если это особый проект, где их много, то можно отключить диагностику.
И правильно что ругается, ибо каждый раз нужно вспоминать (или подглядывать) приоритет операций. Если лишнее — эту диагностику можно отключить. В данном случае ситуация ещё усугубляется повторяющимися скобками.
gcc и так понял
Да. Но нашли ошибку мы. :) Мощь PVS-Studio.
Как я понимаю, варианты бесплатного лицензирования, описанные в этой статье, не подходят по той причине, что Вы делаете маленькие проекты на заказ? Но тогда и проблемы как таковой нет. В маленьких проектах низкая плотность ошибок, и статический анализ не столь актуален, как в больших проектах. Ну или по крайней мере можно использовать более простыми бесплатными анализаторами, такими как Cppcheck.

Если проект большой и над ним работает команда, то не вижу препятствия запросить у заказчика приобретение лицензии.
Или узкая специализация это линия партии?
Пожалуй, да, хотя мы именно так это никогда не формулировали :)
Клиенты довольны. Хейтеры хейтят. Всё как везде и всегда.

Из статьи "Интеграция PVS-Studio в uVision Keil":
И началась эпическая переписка с техподдержкой, которая – исключительно по моей вине – растянулась почти на год (!). Вот честное слово — техподдержка у PVS-Studio – натурально лучшая из всех, с кем я общался, а общался я со многими, от российских производителей микросхем, где человек поздравлял меня с «днём пирожков с малиновым вареньем» (нет, это не шутка) до крупнейших зарубежных компаний, где меня месяцами футболили от человека к человеку :)
Тут же я со стыдом признаюсь, что отвечал существенно медленнее, чем отвечали мне… частично меня оправдывает необходимость заниматься основными рабочими задачами, но только частично.

Information

Rating
263-rd
Works in
Date of birth
Registered
Activity

Specialization

Specialist
C++
C
Software development