如何使用布尔参数为按位运算符启用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
这样的东西应该能够将其作为逻辑错误,因为很明显,在大多数情况下,目的不是将按位运算应用于布尔值,而是逻辑运算。
即使启用了-Wall -Wextra -Wconversion
,g++
似乎也不关心这个问题,这是明智的,因为正如我之前提到的,这并不违反标准。(我什至尝试了g++
6.3,它应该有很多新的检查,但仍然一无所获。
在启用所有检查的情况下使用clang-tidy
(这可能会很快变得非常嘈杂)确实会警告隐式转换本身("隐式强制转换布尔 -> 'int'"),但似乎没有与将按位运算符应用于布尔值相关的特定警告。
以不同的方式编写 if 语句作为if(~foo == true)
,虽然冗长并导致总是错误的场景,但确实会导致更有意义的错误,这可能会引起人们的注意,但是当使用更简洁的if(~foo)
形式时,这种情况不会发生。
是否有任何方法/工具来检查此类问题,这些问题是 100% 正确的C++,但很可能是错误?
从 gcc 7 开始,gcc 中有-Wbool-operation
:
警告布尔类型表达式的可疑操作。例如,布尔值的按位否定很可能是程序中的错误。对于 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 ('!')?
海湾合作委员会演示
不幸的是,叮当 5 似乎没有这样的选择。即使打开(几乎)此处列出的所有可能的警告,我们仍然没有得到预期的警告(演示)(尽管我们确实得到了一些有趣的其他警告)。
最后,为了完整起见,MSVC 19.00.23506 明确警告(演示)(感谢@cbuchart指出这一点):
source_file.cpp(8): warning C4804: '~': unsafe use of type 'bool' in operation
- 编译时未启用intel oneApi CUDA支持
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用布尔参数为按位运算符启用C++警告
- 有条件地启用运算符重载
- 使用 SFINAE 启用转换运算符
- 条件启用替代赋值运算符
- C++ 映射数组运算符重载启用设置值