Search code examples
c++bit-manipulationstatic-analysis

How to enable C++ warnings for bitwise operators with boolean arguments


While working with a rather large C++ code base and the GCC toolchain on Linux, I have encountered code which performs a boolean check as follows:

#include <stdio.h>

int main() {
   bool foo = true;

   if (~foo) {
     // do some expensive operation
     printf("This can be bad...\n");
   }
   return 0;
}

This looks like an obvious bug, since the ~ operator represents bit-wise NOT in C++, and not logical NOT, as it would, say, in MATLAB. The above code would always evaluate to true

Luckily, the issue caused by this bug was not major (it was just a small performance hit), but it got me thinking about how this bug hadn't been found in so much time.

Since the bit-wise operator triggers an implicit cast from the boolean to an integer, which is a promotion, there's nothing wrong with it per se. However, to me it seems as though at least something like clang-tidy should be able to pick this up as a logical error, since it is pretty clear that in most cases, the intent is not to apply a bit-wise operation to a bool, but instead a logical one.

g++ doesn't seem to care about this issue even with -Wall -Wextra -Wconversion enabled, which is sensible given that, as I mentioned before, this isn't against the standard. (I even tried g++ 6.3, which should have a lot of new checks, and still got nothing.)

Using clang-tidy with all checks enabled (which can get really noisy really fast) does warn about the implicit conversion itself ("implicit cast bool -> 'int'"), but there doesn't seem to be a specific warning related to applying bit-wise operators to booleans.

Writing the if-statement differently as if(~foo == true), while verbose and leading to an always-false scenario, does lead to more meaningful errors which can bring the bug into attention, but this doesn't happen when the terser if(~foo) form is used.

Are there any ways/tools to check for such issues, which are 100% correct C++, but very likely bugs?


Solution

  • There is -Wbool-operation in gcc as of gcc 7:

    Warn about suspicious operations on expressions of a boolean type. For instance, bitwise negation of a boolean is very likely a bug in the program. For C, this warning also warns about incrementing or decrementing a boolean, which rarely makes sense. (In C++, decrementing a boolean is always invalid. Incrementing a boolean is invalid in C++1z, and deprecated otherwise.)

    This warning is enabled by -Wall.

    It provides the following warning for your program:

    prog.cc:6:9: warning: '~' on an expression of type bool [-Wbool-operation]
        if (~foo) {
             ^~~
    prog.cc:6:9: note: did you mean to use logical not ('!')?
    

    gcc demo

    Unfortunately it does not appear that clang 5 has such an option. Even turning on (quite nearly) all of the possible warnings listed here, we still don't get the expected warning (Demo) (although we do get a few interesting others).

    Finally, for completeness, MSVC 19.00.23506 definitely warns (Demo) (credit to @cbuchart for pointing this out):

    source_file.cpp(8): warning C4804: '~': unsafe use of type 'bool' in operation