readability-magic-numbers

检测代码中嵌入的魔法数字,即未通过常量或符号引入的整数或浮点数字面量。

许多编码规范建议使用符号常量替换魔法值,以提高可读性。以下是一些参考资料

魔法值的示例

template<typename T, size_t N>
struct CustomType {
   T arr[N];
};

struct OtherType {
   CustomType<int, 30> container;
}
CustomType<int, 30> values;

double circleArea = 3.1415926535 * radius * radius;

double totalCharge = 1.08 * itemPrice;

int getAnswer() {
   return -3; // FILENOTFOUND
}

for (int mm = 1; mm <= 12; ++mm) {
   std::cout << month[mm] << '\n';
}

重构后的魔法值示例

template<typename T, size_t N>
struct CustomType {
   T arr[N];
};

const size_t NUMBER_OF_ELEMENTS = 30;
using containerType = CustomType<int, NUMBER_OF_ELEMENTS>;

struct OtherType {
   containerType container;
}
containerType values;

double circleArea = M_PI * radius * radius;

const double TAX_RATE = 0.08;  // or make it variable and read from a file

double totalCharge = (1.0 + TAX_RATE) * itemPrice;

int getAnswer() {
   return E_FILE_NOT_FOUND;
}

for (int mm = 1; mm <= MONTHS_IN_A_YEAR; ++mm) {
   std::cout << month[mm] << '\n';
}

对于整数字面量,默认情况下,只有 01(以及 -1)整数值在没有警告的情况下被接受。这可以通过 IgnoredIntegerValues 选项进行覆盖。如果负值的绝对值存在于 IgnoredIntegerValues 列表中,则接受负值。

作为整数值的特殊情况,可以通过启用 IgnorePowersOf2IntegerValues 选项来接受所有 2 的幂次方整数值而不会发出警告。

对于浮点数字面量,默认情况下,0.0 浮点值在没有警告的情况下被接受。可以使用 IgnoredFloatingPointValues 选项配置忽略的浮点数字面量集。对于该集中每个值,给定字符串值将转换为目标架构使用的浮点值表示形式。如果浮点数字面量值与其中一个转换后的值相等,则此检查不会诊断该字面量。由于使用浮点相等性来确定是否进行诊断,因此用户需要了解目标架构无法精确表示的任何值的浮点表示的详细信息。

对于 IgnoredFloatingPointValues 集中的每个值,都接受单精度形式和双精度形式(例如,如果 3.14 位于该集中,则 3.14f 和 3.14 都不会产生警告)。

科学计数法在源代码输入和选项中都受支持。或者,可以通过启用 IgnoreAllFloatingPointValues 选项来禁用对所有浮点数的检查。

由于 00.0 作为循环的基本计数器或总和的初始化值非常常见,因此即使它们未出现在相应的忽略值列表中,它们也始终在没有警告的情况下被接受。

选项

IgnoredIntegerValues

以分号分隔的魔法正整数列表,这些整数将在没有警告的情况下被接受。默认值为 {1, 2, 3, 4},并且 0 无条件接受。

IgnorePowersOf2IntegerValues

表示是否接受所有 2 的幂次方整数值而不发出警告的布尔值。默认值为 false

IgnoredFloatingPointValues

以分号分隔的魔法正浮点值列表,这些值将在没有警告的情况下被接受。默认值为 {1.0, 100.0},并且 0.0 无条件接受。

IgnoreAllFloatingPointValues

表示是否接受所有浮点值而不发出警告的布尔值。默认值为 false

IgnoreBitFieldsWidths

表示是否接受魔法数字作为位域宽度而不发出警告的布尔值。这在例如从硬件规范生成的寄存器定义中很有用。默认值为 true

IgnoreTypeAliases

表示是否接受 typedefusing 声明中的魔法数字的布尔值。默认值为 false

IgnoreUserDefinedLiterals

表示是否接受用户定义字面量中的魔法数字的布尔值。默认值为 false