运算结果不应溢出
10.2.9 ID_evalOverflow
溢出即运算结果超出了对应类型的取值范围,使相关数据无法被完整存储,造成数据丢失。
有符号整型和浮点型溢出会导致标准未定义的行为。无符号整数的运算结果是数学上的结果与无符号整型最大值求模的结果,标准认为这是一种算法特性,规定无符号整型不存在溢出,然而实践表明,运算结果超出取值范围往往意味着错误。
示例:
int32_t mul(int32_t a, int32_t b)
{
return a * b; // May overflow or underflow
}
例中 32 位整数相乘可能产生溢出,使函数返回错误结果。
应对溢出作出判断:
int32_t mul(int32_t a, int32_t b)
{
int64_t r = static_cast<int64_t>(a) * b;
if (r > INT32_MAX) {
throw Overflow();
}
if (r < INT32_MIN) {
throw Underflow();
}
return static_cast<int32_t>(r); // Safe result
}
其中 INT32_MAX 和 INT32_MIN 分别为 32 位整数的最大值与最小值。
依据
ISO/IEC 9899:1999 6.2.5(9)
ISO/IEC 9899:1999 6.5(5)-undefined
ISO/IEC 9899:2011 6.2.5(9)
ISO/IEC 9899:2011 6.5(5)-undefined
ISO/IEC 14882:2003 5(5)-undefined
ISO/IEC 14882:2011 5(4)-undefined