如何使用布尔参数为按位运算符启用C++警告

And*_*san 20 c++ static-analysis bit-manipulation

在Linux上使用相当大的C++代码库和GCC工具链时,我遇到了执行布尔检查的代码,如下所示:

#include <stdio.h>

int main() {
   bool foo = true;

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

这看起来像一个明显的错误,因为~运算符在C++中表示逐位NOT,而不是逻辑NOT,就像在MATLAB中那样.上面的代码总是评估为true

幸运的是,这个错误造成的问题不是很重要(这只是一个小小的性能损失),但它让我想到如何在这么多时间内找不到这个错误.

由于逐位运算符触发从布尔值到整数的隐式转换(这是一个促销),因此它本身没有任何问题.然而,对我而言,似乎至少clang-tidy应该能够将其视为逻辑错误,因为很明显,在大多数情况下,意图不是对bool应用逐位操作,而是而是一个逻辑的.

g++即使-Wall -Wextra -Wconversion启用也似乎并不关心这个问题,这是明智的,因为正如我之前提到的,这不符合标准.(我甚至试过g++6.3,它应该有很多新的检查,但仍然没有任何结果

使用clang-tidy所有启用的检查(真的很快就会变得嘈杂)会警告隐式转换本身("隐式转换bool - >'int'"),但似乎没有与应用bit-相关的特定警告聪明的操作员到布尔.

以不同的方式编写if语句if(~foo == true),虽然详细并导致始终为false的情况,但确实会导致更有意义的错误,从而引起注意,但是在使用terser if(~foo)表单时不会发生这种情况.

是否有任何方法/工具来检查这些问题,这些问题是100%正确的C++,但很可能是错误?

And*_*dyG 24

-Wbool-operation在gcc作为GCC 7:

警告布尔类型表达式的可疑操作.例如,布尔值的按位否定很可能是程序中的错误.对于C,此警告还警告增加或减少布尔值,这很少有意义.(在C++中,递减布尔值总是无效的.在C++ 1z中增加布尔值是无效的,否则就弃用了.)

-Wall启用此警告.

它为您的程序提供以下警告:

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 ('!')?
Run Code Online (Sandbox Code Playgroud)

gcc演示

不幸的是,clang 5似乎没有这样的选择.即使打开(非常接近)此处列出的所有可能的警告,我们仍然没有得到预期的警告(演示)(尽管我们确实得到了一些有趣的其他警告).

最后,为了完整性,MSVC 19.00.23506明确警告(演示)(归功于@cbuchart指出这一点):

source_file.cpp(8): warning C4804: '~': unsafe use of type 'bool' in operation
Run Code Online (Sandbox Code Playgroud)

  • 我在手册中看到了这个选项,看到它是由`-Wall`启用的,这是我所拥有的一个标志,所以我认为它没有因某种原因检测到这个特殊情况.它似乎不适用于gcc/g ++ 6; 接得好!第二次编辑:可以确认它适用于`g ++ - 7`! (5认同)
  • 有关较早方面另一个更新我忘了提:与项目的问题是,它是一个CUDA之一,所以我们不能使用任何GCC更新超过540 ...(你的答案不相关,只是觉得应该点那......) (3认同)