Avoid the use of magic numbers in code when possible. Magic numbers are constant values that represent either an arbitrary value (such as a determined appropriate buffer size) or a malleable concept (such as the age a person is considered an adult, which could change between geopolitical boundaries). Rather, use appropriately named symbolic constants to clarify the intent of the code. In addition, if a specific value needs to be changed, reassigning a symbolic constant once is more efficient and less error prone than replacing every instance of the value.
The meaning of the numeric literal 18 is not clear in this example.
/* ... */ if (age >= 18) { /* Take action */ } else { /* Take a different action */ } /* ... */ |
The compliant solution replaces 18 with the symbolic constant ADULT_AGE
to clarify the meaning of the code.
When declaring immutable symbolic values, such as ADULT_AGE
, it is best to declare them as a constant in accordance with DCL00-A. Declare immutable values using enum or const.
enum { ADULT_AGE=18 }; /* ... */ if (age >= ADULT_AGE) { /* Take action */ } else { /* Take a different action */ } /* ... */ |
DCL06-EX1: While replacing numeric constants with a symbolic constant is often a good practice, it can be taken too far. Exceptions can be made for constants that are themselves the abstraction you want to represent, as in this compliant solution.
x = (-b + sqrt(b*b - 4*a*c)) / (2*a); |
Replacing numeric constants with symbolic constants in this example does nothing to improve the readability of the code, and may in fact make the code more difficult to read:
enum { TWO = 2 }; /* a scalar */ enum { FOUR = 4 }; /* a scalar */ enum { SQUARE = 2 }; /* an exponent */ x = (-b + sqrt(pow(b, SQUARE) - FOUR*a*c))/ (TWO * a); |
When implementing recommendations, it is always necessary to use sound judgment.
Using numeric literals makes code more difficult to read and understand. Buffer overruns are frequently a consequence of a magic number being changed in one place (like an array declaration) but not elsewhere (like a loop through an array).
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
DCL06-A |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[Henricson 1992|AA. C References#Henricson 1992]\] Chapter 10, "[Constants|http://www.doc.ic.ac.uk/lab/cplus/c++.rules/chap10.html]" \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7, "Declarations" |
DCL05-A. Use typedefs to improve code readability 02. Declarations and Initialization (DCL) DCL07-A. Include the appropriate type information in function declarators