1.. title:: clang-tidy - readability-magic-numbers 2 3readability-magic-numbers 4========================= 5 6Detects magic numbers, integer or floating point literals that are embedded in 7code and not introduced via constants or symbols. 8 9Many coding guidelines advise replacing the magic values with symbolic 10constants to improve readability. Here are a few references: 11 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." 17 by Robert C. Martin 18 * Rule 20701 in "TRAIN REAL TIME DATA PROTOCOL Coding Rules" by Armin-Hagen 19 Weiss, Bombardier 20 * http://wiki.c2.com/?MagicNumber 21 22 23Examples of magic values: 24 25.. code-block:: c++ 26 27 template<typename T, size_t N> 28 struct CustomType { 29 T arr[N]; 30 }; 31 32 struct OtherType { 33 CustomType<int, 30> container; 34 } 35 CustomType<int, 30> values; 36 37 double circleArea = 3.1415926535 * radius * radius; 38 39 double totalCharge = 1.08 * itemPrice; 40 41 int getAnswer() { 42 return -3; // FILENOTFOUND 43 } 44 45 for (int mm = 1; mm <= 12; ++mm) { 46 std::cout << month[mm] << '\n'; 47 } 48 49Example with magic values refactored: 50 51.. code-block:: c++ 52 53 template<typename T, size_t N> 54 struct CustomType { 55 T arr[N]; 56 }; 57 58 const size_t NUMBER_OF_ELEMENTS = 30; 59 using containerType = CustomType<int, NUMBER_OF_ELEMENTS>; 60 61 struct OtherType { 62 containerType container; 63 } 64 containerType values; 65 66 double circleArea = M_PI * radius * radius; 67 68 const double TAX_RATE = 0.08; // or make it variable and read from a file 69 70 double totalCharge = (1.0 + TAX_RATE) * itemPrice; 71 72 int getAnswer() { 73 return E_FILE_NOT_FOUND; 74 } 75 76 for (int mm = 1; mm <= MONTHS_IN_A_YEAR; ++mm) { 77 std::cout << month[mm] << '\n'; 78 } 79 80For integral literals by default only `0` and `1` (and `-1`) integer values 81are accepted without a warning. This can be overridden with the 82:option:`IgnoredIntegerValues` option. Negative values are accepted if their 83absolute value is present in the :option:`IgnoredIntegerValues` list. 84 85As a special case for integral values, all powers of two can be accepted 86without warning by enabling the :option:`IgnorePowersOf2IntegerValues` option. 87 88For floating point literals by default the `0.0` floating point value is 89accepted without a warning. The set of ignored floating point literals can 90be configured using the :option:`IgnoredFloatingPointValues` option. 91For each value in that set, the given string value is converted to a 92floating-point value representation used by the target architecture. If a 93floating-point literal value compares equal to one of the converted values, 94then that literal is not diagnosed by this check. Because floating-point 95equality is used to determine whether to diagnose or not, the user needs to 96be aware of the details of floating-point representations for any values that 97cannot be precisely represented for their target architecture. 98 99For each value in the :option:`IgnoredFloatingPointValues` set, both the 100single-precision form and double-precision form are accepted (for example, if 1013.14 is in the set, neither 3.14f nor 3.14 will produce a warning). 102 103Scientific notation is supported for both source code input and option. 104Alternatively, the check for the floating point numbers can be disabled for 105all floating point values by enabling the 106:option:`IgnoreAllFloatingPointValues` option. 107 108Since values `0` and `0.0` are so common as the base counter of loops, 109or initialization values for sums, they are always accepted without warning, 110even if not present in the respective ignored values list. 111 112Options 113------- 114 115.. option:: IgnoredIntegerValues 116 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 119 unconditionally. 120 121.. option:: IgnorePowersOf2IntegerValues 122 123 Boolean value indicating whether to accept all powers-of-two integer values 124 without warning. Default value is `false`. 125 126.. option:: IgnoredFloatingPointValues 127 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. 131 132.. option:: IgnoreAllFloatingPointValues 133 134 Boolean value indicating whether to accept all floating point values without 135 warning. Default value is `false`. 136 137.. option:: IgnoreBitFieldsWidths 138 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`. 142 143.. option:: IgnoreTypeAliases 144 145 Boolean value indicating whether to accept magic numbers in ``typedef`` or 146 ``using`` declarations. Default value is `false`. 147 148.. option:: IgnoreUserDefinedLiterals 149 150 Boolean value indicating whether to accept magic numbers in user-defined 151 literals. Default value is `false`. 152