bugprone-implicit-widening-of-multiplication-result¶
此检查诊断了乘法结果被隐式扩展的情况,并建议(通过 fix-it)通过使扩展显式来消除代码,或者在更宽的类型中执行乘法,以避免之后的扩展。
这主要在操作非常大的缓冲区时有用。例如,考虑
void zeroinit(char* base, unsigned width, unsigned height) {
for(unsigned row = 0; row != height; ++row) {
for(unsigned col = 0; col != width; ++col) {
char* ptr = base + row * width + col;
*ptr = 0;
}
}
}
这在一般情况下是正常的,但是如果 width * height
溢出,你最终会回绕到 base
的开头,而不是处理整个请求的缓冲区。
实际上,这只有在非常大的缓冲区(4GB+)时才会发生,但这很容易发生,例如在图像处理中,为了发生这种情况,你“只需要”一个大约 269MPix 的图像。
选项¶
- UseCXXStaticCastsInCppSources¶
在为 C++ 代码建议 fix-it 时,是否应该建议 C++ 风格的
static_cast<>()
,还是 C 风格的强制转换。默认为true
。
- UseCXXHeadersInCppSources¶
在建议在 C++ 代码中包含适当的头文件时,是否应该建议
<cstddef>
头文件,还是<stddef.h>
。默认为true
。
- IgnoreConstantIntExpr¶
如果乘法操作数是编译时常量(例如字面量或
constexpr
)并且适合源表达式类型,则不发出诊断或建议的修复。仅考虑源表达式是带符号整数类型的表达式。默认为false
。
示例
long mul(int a, int b) {
return a * b; // warning: performing an implicit widening conversion to type 'long' of a multiplication performed in type 'int'
}
char* ptr_add(char *base, int a, int b) {
return base + a * b; // warning: result of multiplication in type 'int' is used as a pointer offset after an implicit widening conversion to type 'ssize_t'
}
char ptr_subscript(char *base, int a, int b) {
return base[a * b]; // warning: result of multiplication in type 'int' is used as a pointer offset after an implicit widening conversion to type 'ssize_t'
}