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)
不幸的是,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)