You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 51 Next »

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.

Non-Compliant Code Example

The meaning of the numeric literal 18 is not clear in this example.

/* ... */
if (age >= 18) {
   /* Take action */
}
else {
  /* Take a different action */
}
/* ... */

Compliant Solution

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 */
}
/* ... */

Exceptions

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.

Risk Assessment

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.

References

[[Henricson 92]] Chapter 10, "Constants"
[[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

  • No labels