1 .. title:: clang-tidy - readability-magic-numbers
3 readability-magic-numbers
4 =========================
6 Detects magic numbers, integer or floating point literals that are embedded in
7 code and not introduced via constants or symbols.
9 Many coding guidelines advise replacing the magic values with symbolic
10 constants to improve readability. Here are a few references:
12 * `Rule ES.45: Avoid "magic constants"; use symbolic constants in C++ Core Guidelines <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-magic>`_
13 * `Rule 5.1.1 Use symbolic names instead of literal values in code in High Integrity C++ <https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard-expressions>`_
14 * Item 17 in "C++ Coding Standards: 101 Rules, Guidelines and Best
15 Practices" by Herb Sutter and Andrei Alexandrescu
16 * Chapter 17 in "Clean Code - A handbook of agile software craftsmanship."
18 * Rule 20701 in "TRAIN REAL TIME DATA PROTOCOL Coding Rules" by Armin-Hagen
20 * http://wiki.c2.com/?MagicNumber
23 Examples of magic values:
27 template<typename T, size_t N>
33 CustomType<int, 30> container;
35 CustomType<int, 30> values;
37 double circleArea = 3.1415926535 * radius * radius;
39 double totalCharge = 1.08 * itemPrice;
42 return -3; // FILENOTFOUND
45 for (int mm = 1; mm <= 12; ++mm) {
46 std::cout << month[mm] << '\n';
49 Example with magic values refactored:
53 template<typename T, size_t N>
58 const size_t NUMBER_OF_ELEMENTS = 30;
59 using containerType = CustomType<int, NUMBER_OF_ELEMENTS>;
62 containerType container;
66 double circleArea = M_PI * radius * radius;
68 const double TAX_RATE = 0.08; // or make it variable and read from a file
70 double totalCharge = (1.0 + TAX_RATE) * itemPrice;
73 return E_FILE_NOT_FOUND;
76 for (int mm = 1; mm <= MONTHS_IN_A_YEAR; ++mm) {
77 std::cout << month[mm] << '\n';
80 For integral literals by default only `0` and `1` (and `-1`) integer values
81 are accepted without a warning. This can be overridden with the
82 :option:`IgnoredIntegerValues` option. Negative values are accepted if their
83 absolute value is present in the :option:`IgnoredIntegerValues` list.
85 As a special case for integral values, all powers of two can be accepted
86 without warning by enabling the :option:`IgnorePowersOf2IntegerValues` option.
88 For floating point literals by default the `0.0` floating point value is
89 accepted without a warning. The set of ignored floating point literals can
90 be configured using the :option:`IgnoredFloatingPointValues` option.
91 For each value in that set, the given string value is converted to a
92 floating-point value representation used by the target architecture. If a
93 floating-point literal value compares equal to one of the converted values,
94 then that literal is not diagnosed by this check. Because floating-point
95 equality is used to determine whether to diagnose or not, the user needs to
96 be aware of the details of floating-point representations for any values that
97 cannot be precisely represented for their target architecture.
99 For each value in the :option:`IgnoredFloatingPointValues` set, both the
100 single-precision form and double-precision form are accepted (for example, if
101 3.14 is in the set, neither 3.14f nor 3.14 will produce a warning).
103 Scientific notation is supported for both source code input and option.
104 Alternatively, the check for the floating point numbers can be disabled for
105 all floating point values by enabling the
106 :option:`IgnoreAllFloatingPointValues` option.
108 Since values `0` and `0.0` are so common as the base counter of loops,
109 or initialization values for sums, they are always accepted without warning,
110 even if not present in the respective ignored values list.
115 .. option:: IgnoredIntegerValues
117 Semicolon-separated list of magic positive integers that will be accepted
118 without a warning. Default values are `{1, 2, 3, 4}`, and `0` is accepted
121 .. option:: IgnorePowersOf2IntegerValues
123 Boolean value indicating whether to accept all powers-of-two integer values
124 without warning. Default value is `false`.
126 .. option:: IgnoredFloatingPointValues
128 Semicolon-separated list of magic positive floating point values that will
129 be accepted without a warning. Default values are `{1.0, 100.0}` and `0.0`
130 is accepted unconditionally.
132 .. option:: IgnoreAllFloatingPointValues
134 Boolean value indicating whether to accept all floating point values without
135 warning. Default value is `false`.
137 .. option:: IgnoreBitFieldsWidths
139 Boolean value indicating whether to accept magic numbers as bit field widths
140 without warning. This is useful for example for register definitions which
141 are generated from hardware specifications. Default value is `true`.
143 .. option:: IgnoreTypeAliases
145 Boolean value indicating whether to accept magic numbers in ``typedef`` or
146 ``using`` declarations. Default value is `false`.
148 .. option:: IgnoreUserDefinedLiterals
150 Boolean value indicating whether to accept magic numbers in user-defined
151 literals. Default value is `false`.