如何为带有布尔参数的按位运算符启用 C++ 警告
How to enable C++ warnings for bitwise operators with boolean arguments
在 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;
}
这看起来像是一个明显的错误,因为 ~
运算符在 C++ 中表示按位 NOT,而不是逻辑 NOT,例如在 MATLAB 中。上面的代码将始终评估为 true
幸运的是,这个错误引起的问题并不严重(只是性能上的一个小问题),但这让我开始思考为什么这么长时间都没有发现这个错误。
由于按位运算符触发了从布尔值到整数的隐式转换,这是一种提升,因此它本身没有任何问题。但是,对我来说,似乎至少像 clang-tidy
这样的东西应该能够将其视为逻辑错误,因为很明显在大多数情况下, intent 不是对 bool 应用按位运算,而是对逻辑运算。
g++
似乎并不关心这个问题,即使启用了 -Wall -Wextra -Wconversion
,这是明智的,因为正如我之前提到的,这并不违反标准。 (我什至尝试了g++
6.3,应该有很多新的检查,但仍然一无所获
在启用所有检查的情况下使用 clang-tidy
(这会很快变得非常嘈杂)确实会警告隐式转换本身("implicit cast bool -> 'int'"),但似乎没有具体的警告与将按位运算符应用于布尔值有关。
将 if 语句写成与 if(~foo == true)
不同的方式,虽然冗长并导致始终为 false 的情况,但确实会导致更有意义的错误,从而引起 bug 的注意,但这不会发生使用更简洁的 if(~foo)
形式。
是否有任何 ways/tools 检查此类问题,这些问题是 100% 正确的 C++,但很可能是错误?
从 gcc 7 开始,gcc 中有 -Wbool-operation
:
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.
它为您的程序提供以下警告:
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
不幸的是,clang 5 似乎没有这样的选项。甚至打开(几乎)列出的所有可能的警告 here, we still don't get the expected warning (Demo)(尽管我们确实得到了其他一些有趣的警告)。
最后,为了完整起见,MSVC 19.00.23506 明确警告(Demo) (credit to 指出了这一点):
source_file.cpp(8): warning C4804: '~': unsafe use of type 'bool' in operation
在 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;
}
这看起来像是一个明显的错误,因为 ~
运算符在 C++ 中表示按位 NOT,而不是逻辑 NOT,例如在 MATLAB 中。上面的代码将始终评估为 true
幸运的是,这个错误引起的问题并不严重(只是性能上的一个小问题),但这让我开始思考为什么这么长时间都没有发现这个错误。
由于按位运算符触发了从布尔值到整数的隐式转换,这是一种提升,因此它本身没有任何问题。但是,对我来说,似乎至少像 clang-tidy
这样的东西应该能够将其视为逻辑错误,因为很明显在大多数情况下, intent 不是对 bool 应用按位运算,而是对逻辑运算。
g++
似乎并不关心这个问题,即使启用了 -Wall -Wextra -Wconversion
,这是明智的,因为正如我之前提到的,这并不违反标准。 (我什至尝试了g++
6.3,应该有很多新的检查,但仍然一无所获
在启用所有检查的情况下使用 clang-tidy
(这会很快变得非常嘈杂)确实会警告隐式转换本身("implicit cast bool -> 'int'"),但似乎没有具体的警告与将按位运算符应用于布尔值有关。
将 if 语句写成与 if(~foo == true)
不同的方式,虽然冗长并导致始终为 false 的情况,但确实会导致更有意义的错误,从而引起 bug 的注意,但这不会发生使用更简洁的 if(~foo)
形式。
是否有任何 ways/tools 检查此类问题,这些问题是 100% 正确的 C++,但很可能是错误?
从 gcc 7 开始,gcc 中有 -Wbool-operation
:
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.
它为您的程序提供以下警告:
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
不幸的是,clang 5 似乎没有这样的选项。甚至打开(几乎)列出的所有可能的警告 here, we still don't get the expected warning (Demo)(尽管我们确实得到了其他一些有趣的警告)。
最后,为了完整起见,MSVC 19.00.23506 明确警告(Demo) (credit to
source_file.cpp(8): warning C4804: '~': unsafe use of type 'bool' in operation