readability-implicit-bool-conversion¶
此检查用于查找内置类型和布尔值之间的隐式转换。根据用例,它可能只是帮助提高代码的可读性,或者在某些情况下,指出由于隐式转换而未被注意到的潜在错误。
以下是一个隐藏在隐式 bool
转换背后的实际错误示例
class Foo {
int m_foo;
public:
void setFoo(bool foo) { m_foo = foo; } // warning: implicit conversion bool -> int
int getFoo() { return m_foo; }
};
void use(Foo& foo) {
bool value = foo.getFoo(); // warning: implicit conversion int -> bool
}
此代码是重构失败的结果,其中 m_foo
的类型从 bool
更改为 int
。程序员忘记更改所有 bool
的出现位置,剩余的代码不再正确,但它仍然可以编译而没有任何明显的警告。
除了发出警告之外,还提供修复建议来帮助解决报告的问题。这可用于改进代码的可读性,例如
void conversionsToBool() {
float floating;
bool boolean = floating;
// ^ propose replacement: bool boolean = floating != 0.0f;
int integer;
if (integer) {}
// ^ propose replacement: if (integer != 0) {}
int* pointer;
if (!pointer) {}
// ^ propose replacement: if (pointer == nullptr) {}
while (1) {}
// ^ propose replacement: while (true) {}
}
void functionTakingInt(int param);
void conversionsFromBool() {
bool boolean;
functionTakingInt(boolean);
// ^ propose replacement: functionTakingInt(static_cast<int>(boolean));
functionTakingInt(true);
// ^ propose replacement: functionTakingInt(1);
}
通常,将检查以下转换类型
整数表达式/字面量到布尔值(从单个位位域到布尔值的转换明确允许,因为在这种情况下没有歧义/信息丢失),
浮点表达式/字面量到布尔值,
指针/指向成员的指针/
nullptr
/NULL
到布尔值,布尔表达式/字面量到整数(从布尔值到单个位位域的转换明确允许),
布尔表达式/字面量到浮点。
生成修复建议的规则是
在从其他内置类型到 bool 的转换的情况下,建议使用显式比较,以明确说明正在比较的内容
bool boolean = floating;
将更改为bool boolean = floating == 0.0f;
,对于其他类型,将使用适当的字面量(
0
、0u
、0.0f
、0.0
、nullptr
),
在否定表达式转换为 bool 的情况下,建议将替换简化为比较
if (!pointer)
将更改为if (pointer == nullptr)
,
在从 bool 到其他内置类型的转换的情况下,建议使用显式
static_cast
(或 C 样式强制转换,因为 C23)以明确说明正在执行转换int integer = boolean;
将更改为int integer = static_cast<int>(boolean);
,
如果对类型字面量执行转换,则将根据实际期望的类型建议使用等效的字面量,例如
functionTakingBool(0);
将更改为functionTakingBool(false);
,functionTakingInt(true);
将更改为functionTakingInt(1);
,对于其他类型,将使用适当的字面量(
false
、true
、0
、1
、0u
、1u
、0.0f
、1.0f
、0.0
、1.0f
)。
对 C++11 之前的方言进行了一些额外的调整
false
字面量转换为指针将被检测到,而不是
nullptr
字面量,建议使用0
作为替换。
宏和模板实例化内部的隐式转换将被故意忽略,因为不清楚如何处理此类情况。
选项¶
- AllowIntegerConditions¶
当为 true 时,检查将允许有条件的整数转换。默认值为 false。
- AllowPointerConditions¶
当为 true 时,检查将允许有条件的指针转换。默认值为 false。
- UseUpperCaseLiteralSuffix¶
当为 true 时,替换将在提供的修复中使用大写字面量后缀。默认值为 false。
示例
uint32_t foo; if (foo) {} // ^ propose replacement default: if (foo != 0u) {} // ^ propose replacement with option `UseUpperCaseLiteralSuffix`: if (foo != 0U) {}