При работе с довольно большой базой кода С++ и инструментальной связью GCC в Linux я столкнулся с кодом, который выполняет логическую проверку следующим образом:
#include <stdio.h>
int main() {
bool foo = true;
if (~foo) {
// do some expensive operation
printf("This can be bad...\n");
}
return 0;
}
Это выглядит как очевидная ошибка, поскольку оператор ~
представляет бит-мудрый NOT на С++, а не логический NOT, как это было бы, скажем, в MATLAB. Вышеприведенный код всегда будет иметь значение true
К счастью, проблема, вызванная этой ошибкой, не была значительной (это был всего лишь небольшой удар по производительности), но мне стало интересно, как эта ошибка не была обнаружена за такое время.
Поскольку бит-мудрый оператор запускает неявное преобразование из булева в целое, что является продвижением по службе, в нем нет ничего плохого. Тем не менее, мне кажется, что хотя бы что-то вроде clang-tidy
должно быть в состоянии выбрать это как логическую ошибку, так как довольно ясно, что в большинстве случаев цель заключается не в применении побитовой операции к bool, но вместо этого логический.
g++
, похоже, не заботится об этой проблеме даже при включенном -Wall -Wextra -Wconversion
, что разумно, учитывая, что, как я упоминал ранее, это не соответствует стандарту. (Я даже пробовал g++
6.3, который должен иметь много новых проверок и все равно ничего не получил
Использование clang-tidy
со всеми включенными проверками (которые действительно могут быть очень шумными) предупреждает о неявном преобразовании ( "implicit cast bool → " int "), но, похоже, не существует конкретной предупреждение, связанное с применением битовых операторов к булевым файлам.
Написание if-утверждения по-разному как if(~foo == true)
, в то время как подробный и приводящий к всегда-ложному сценарию, приводит к более значимым ошибкам, которые могут привнести внимание к проблеме, но этого не происходит, когда terser if(~foo)
.
Существуют ли какие-либо способы/инструменты для проверки таких проблем, которые на 100% правильны для С++, но очень вероятные ошибки?