cppcoreguidelines-narrowing-conversions¶
检查隐式缩窄转换,例如:int i = 0; i += 0.1;
。虽然在这个例子中问题很明显,但在以下情况下可能就不是那么明显了:void MyClass::f(double d) { int_member_ += d; }
。
此检查实现了 C++ Core Guidelines 中的 ES.46。
- 我们只强制执行指南的一部分,更具体地说,我们标记从
整数到更窄的整数(例如
char
到unsigned char
)的缩窄转换,如果设置了 WarnOnIntegerNarrowingConversion 选项,整数到更窄的浮点数(例如
uint64_t
到float
)的缩窄转换,如果设置了 WarnOnIntegerToFloatingPointNarrowingConversion 选项,浮点数到整数(例如
double
到int
),浮点数到更窄的浮点数(例如
double
到float
)的缩窄转换,如果设置了 WarnOnFloatingPointNarrowingConversion 选项。
- 此检查将标记
所有没有用显式转换(c 样式或
static_cast
)标记的缩窄转换。例如:int i = 0; i += 0.1;
,void f(int); f(0.1);
,所有使用缩窄转换的二元运算符的应用。例如:
int i; i+= 0.1;
。
选项¶
- WarnOnIntegerNarrowingConversion¶
当为 true 时,检查将警告整数缩窄转换(例如
int
到size_t
)。默认值为 true。
- WarnOnIntegerToFloatingPointNarrowingConversion¶
当为 true 时,检查将警告整数到浮点数的缩窄转换(例如
size_t
到double
)。默认值为 true。
- WarnOnFloatingPointNarrowingConversion¶
当为 true 时,检查将警告浮点数缩窄转换(例如
double
到float
)。默认值为 true。
- WarnWithinTemplateInstantiation¶
当为 true 时,检查将在模板实例化中警告缩窄转换。默认值为 false。
- WarnOnEquivalentBitWidth¶
当为 true 时,检查将警告在具有等效位宽的类型之间进行转换时出现的缩窄转换。(例如 int n = uint(0); 或 long long n = double(0);) 默认值为 true。
- IgnoreConversionFromTypes¶
将忽略从此分号分隔列表中的任何类型进行的缩窄转换。这对于剔除常见的但不太常见的问题赋值可能很有用,例如 int n = std::vector<char>().size(); 或 int n = std::difference(it1, it2);。默认列表为空,但对于遗留代码库,一个建议的列表是 size_t;ptrdiff_t;size_type;difference_type。
- PedanticMode¶
当为 true 时,即使浮点值在目标类型中完全可表示,检查也会警告将浮点常量分配给整数值(例如
int i = 1.0;
)。默认值为 false。
常见问题解答¶
“从 ‘int’ 到 ‘float’ 的缩窄转换”是什么意思?
IEEE754 浮点数可以表示范围 [-2^PrecisionBits, 2^PrecisionBits] 内的所有整数值,其中 PrecisionBits 是尾数中的位数。
对于 float
,这将是 [-2^23, 2^23],其中 int
可以表示范围 [-2^31, 2^31-1] 内的值。
“实现定义的”是什么意思?
您可能遇到过类似“从 ‘unsigned int’ 到有符号类型 ‘int’ 的缩窄转换是实现定义的”的消息。C/C++ 标准没有为有符号整数规定二进制补码,因此编译器可以自由定义将无符号整数转换为有符号整数的语义。Clang 的实现使用二进制补码格式。