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'
}