Не очень понятная дискуссия :). Я ведь не то, чтобы спорю :). "Творческий" в том плане, что провоцирует большее количество ошибок, связанных с невнимательностью. Хотя формально разницы нет, будет истина 1 или -1.
Это интересный комментарий, который я использую при случае для написания статьи. Спасибо за тему для дискуссии :).
Статический анализ работает не так. Его задача не в том, чтобы отличать некомпилируемый код от компилируемого. С этим отлично справляются компиляторы. Смысл состоит в поиске синтаксически корректных конструкций, которые с большой вероятностью работают не так, как планировалось, или вообще не работают.
Например, код вида:
if (A == A)
компилируется, однако почти наверняка он ошибочен. О наличии такого кода и должен предупредить статический анализатор кода (V501). И благодаря тому, что анализатор обращает внимание на такой, корректный с точки зрения компилятора код, можно выявить множество ошибок. Да, есть экзотическое использование такой конструкции для проверки float/double переменных на равенство NaN. Но это особый случай, про который статические анализаторы тоже в курсе (по крайней мере, про это знает PVS-Studio).
Автор статьи и, думаю, автор вопроса, отлично понимает, как работают неявные приведения типов или вызов виртуальных функций в конструкторах и деструкторах. Все понимают, что стандарт точно определяет, как будет работать этот код. Суть в другом. Такие конструкции крайне подозрительны и/или потенциально опасны. Выдавая предупреждения, анализатор предлагает дополнительно перепроверить код. Дальше есть три варианта.
Вариант 1. Код ошибочек и его нужно исправить.
Вариант 2. Код корректен, но с запахом. В этом случае лучше провести рефакторинг. Например написать так:
bool a1 = a != 0;
Вариант 3. Это действительно ложное срабатывание. Его можно подавить различными способами.
В любом случае, то, что хочет искать человек, - места с сильным запахом, подверженные ошибкам. Есть смысл задавать вопрос на StackOverflow и использовать статический анализ кода для поиска таких паттернов кода.
Например, вот случай, когда явное присваивание в переменную типа bool значения, выходящего за диапазон [0..1], свидетельствует о настоящей ошибке. Я нашёл это в ОС Tizen.
Хотели записать значение в переменную reporter_server, но промахнулись. И записали в переменную services_supported типа bool.
По поводу виртуальных функций. Эта известная тема. Классика хождения по граблям. У нас даже вопрос на собеседовании есть про вызов виртуальные функции в деструкторе. Ибо опасная тема. И хорошо, если анализатор предложит перепроверить такой код.
Да, всё верно. Подтверждаю, ругаться на такие выражения как if (result) смысла нет. Собственно, PVS-Studio на них и не ругается (и для C для C++). Слишком много срабатываний.
Хотя нет, есть например, вот такой вариант аномальной проверки: if (enum_var) V768. Но эта другая история.
К сожалению, не понял этот комментарий и вообще эту ветку обсуждения. При чём здесь упаковка и т.д... Да, бывают "особые" boolean типы. Например, существует творческий VARIANT_BOOL, для которого истина задаётся как -1. Однако, это отдельная история, не имеющая отношения к bool.
Правила преобразования bool чётки и понятны. Однако, некоторые из таких преобразований странны и могут являться признаком наличия в коде ошибки. Такой странностью является запись в переменную bool значения отличного от 0/1/false/true. Именно аномальные преобразования и хочет обнаруживать человек, задающий вопрос.
Даже если логика кода верна, то всё равно лучше явно писать что-то в духе:
Проблема остановки (англ.Halting problem) — это одна из проблем в теории алгоритмов[1], которая может неформально быть поставлена в виде:
Даны описание процедуры и её начальные входные данные. Требуется определить: завершится ли когда-либо выполнение процедуры с этими данными; либо, что процедура всё время будет работать без остановки.
Почему зря? Мне кажется, такой вариант смотрится лучше: (len1+len2+1)*sizeof(char). А до этого смешивалось понятие длины строк и размера терминально символа.
Не очень понятная дискуссия :). Я ведь не то, чтобы спорю :). "Творческий" в том плане, что провоцирует большее количество ошибок, связанных с невнимательностью. Хотя формально разницы нет, будет истина 1 или -1.
Это интересный комментарий, который я использую при случае для написания статьи. Спасибо за тему для дискуссии :).
Статический анализ работает не так. Его задача не в том, чтобы отличать некомпилируемый код от компилируемого. С этим отлично справляются компиляторы. Смысл состоит в поиске синтаксически корректных конструкций, которые с большой вероятностью работают не так, как планировалось, или вообще не работают.
Например, код вида:
компилируется, однако почти наверняка он ошибочен. О наличии такого кода и должен предупредить статический анализатор кода (V501). И благодаря тому, что анализатор обращает внимание на такой, корректный с точки зрения компилятора код, можно выявить множество ошибок. Да, есть экзотическое использование такой конструкции для проверки
float/double
переменных на равенство NaN. Но это особый случай, про который статические анализаторы тоже в курсе (по крайней мере, про это знает PVS-Studio).Автор статьи и, думаю, автор вопроса, отлично понимает, как работают неявные приведения типов или вызов виртуальных функций в конструкторах и деструкторах. Все понимают, что стандарт точно определяет, как будет работать этот код. Суть в другом. Такие конструкции крайне подозрительны и/или потенциально опасны. Выдавая предупреждения, анализатор предлагает дополнительно перепроверить код. Дальше есть три варианта.
Вариант 1. Код ошибочек и его нужно исправить.
Вариант 2. Код корректен, но с запахом. В этом случае лучше провести рефакторинг. Например написать так:
Вариант 3. Это действительно ложное срабатывание. Его можно подавить различными способами.
В любом случае, то, что хочет искать человек, - места с сильным запахом, подверженные ошибкам. Есть смысл задавать вопрос на StackOverflow и использовать статический анализ кода для поиска таких паттернов кода.
Например, вот случай, когда явное присваивание в переменную типа
bool
значения, выходящего за диапазон [0..1], свидетельствует о настоящей ошибке. Я нашёл это в ОС Tizen.Хотели записать значение в переменную
reporter_server
, но промахнулись. И записали в переменнуюservices_supported
типаbool
.По поводу виртуальных функций. Эта известная тема. Классика хождения по граблям. У нас даже вопрос на собеседовании есть про вызов виртуальные функции в деструкторе. Ибо опасная тема. И хорошо, если анализатор предложит перепроверить такой код.
Согласен. Но обычно воспринимается это так.
Спасибо. Вот, кстати, пара публикаций на эту тему, быть может покажется интересным:
PVS-Studio теперь в Compiler Explorer;
Анализатор PVS-Studio на сайте godbolt.org (Compiler Explorer) и предостережение.
Да, всё верно. Подтверждаю, ругаться на такие выражения как if (result) смысла нет. Собственно, PVS-Studio на них и не ругается (и для C для C++). Слишком много срабатываний.
Хотя нет, есть например, вот такой вариант аномальной проверки: if (enum_var) V768. Но эта другая история.
К сожалению, не понял этот комментарий и вообще эту ветку обсуждения. При чём здесь упаковка и т.д... Да, бывают "особые" boolean типы. Например, существует творческий
VARIANT_BOOL
, для которого истина задаётся как-1
. Однако, это отдельная история, не имеющая отношения кbool
.Правила преобразования
bool
чётки и понятны. Однако, некоторые из таких преобразований странны и могут являться признаком наличия в коде ошибки. Такой странностью является запись в переменнуюbool
значения отличного от 0/1/false/true. Именно аномальные преобразования и хочет обнаруживать человек, задающий вопрос.Даже если логика кода верна, то всё равно лучше явно писать что-то в духе:
Исправили. Спс.
Ну это как посмотреть. Проблема остановки:
Прошло 5 лет: 30 лет ядру Linux: поздравление от PVS-Studio.
Обязательно бахнем! Но потом. (с)
Да. Но как уже отметили, тогда уж надо ещё и умножение длины на sizeof для красоты писать.
Чисто теоретически, легче будет переделать на wchar_t.
Почему зря? Мне кажется, такой вариант смотрится лучше:
(len1+len2+1)*sizeof(char)
. А до этого смешивалось понятие длины строк и размера терминально символа.Согласен. Поменял в статье.
PVS-Studio: Online Examples (C, C++).
К сожалению, пока нет. Выписал для будущих доработок dataflow.