Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When used in program logic, literals can reduce the readability of source code. As a result, literals, in general, and integer constants, in particular, are frequently called magic numbers because their purpose is often obscured. Magic numbers can be constant values that represent either an arbitrary value (such as a determined appropriate buffer size) or a malleable concept (such as the age at which a person is considered an adult, which can change between geopolitical boundaries). Rather than embed literals in program logic, 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 [Saks 2002].

The C programming language has several mechanisms for creating named, symbolic constants: const-qualified objects, enumeration constants, and object-like macro definitions. Each of these mechanisms has associated advantages and disadvantages.

...

If any of these are required, then an integer constant (which would be an rvalue) must be used.

const-qualified objects allow the programmer to take the address of the object.

...

const-qualified objects are likely to incur some runtime overhead [Saks 2001b]. Most C compilers, for example, allocate memory for const-qualified objects. const-qualified objects declared inside a function body can have automatic storage duration. If so, the compiler will allocate storage for the object, and it will be on the stack. As a result, this storage will need to be allocated and initialized each time the containing function is invoked.

...

In this compliant solution, the integer literal is replaced with an enumeration constant. (See DCL00-C. Const-qualify immutable objects.)

Code Block
bgColor#ccccff
langc
enum { BUFFER_SIZE=256 };

char buffer[BUFFER_SIZE];
/* ... */
fgets(buffer, BUFFER_SIZE, stdin);

...

Frequently, it is possible to obtain the desired readability by using a symbolic expression composed of existing symbols rather than by defining a new symbol. For example, a sizeof expression can work just as well as an enumeration constant. (See EXP09-C. Use sizeof to determine the size of a type or variable.)

Code Block
bgColor#ccccff
langc
char buffer[256];
/* ... */
fgets(buffer, sizeof(buffer), stdin);

Using the sizeof expression in this example reduces the total number of names declared in the program, which is generally a good idea [Saks 2002]. The sizeof operator is almost always evaluated at compile time (except in the case of variable-length arrays).

When working with sizeof(), keep in mind ARR01-C. Do not apply the sizeof operator to a pointer when taking the size of an array.

Noncompliant Code Example

...

Note that this example does not check for invalid operations (taking the sqrt() of a negative number). See FLP32-C. Prevent or detect domain and range errors in math functions for more information on detecting domain and range errors in math functions.

...

Tool

Version

Checker

Description

LDRA tool suite

Include Page
LDRA_V
LDRA_V

201 S

Fully implemented

Compass/ROSE

 

 

Could detect violations of this recommendation merely by searching for the use of "magic numbers" and magic strings in the code itself. That is, any number (except a few canonical numbers: −1, 0, 1, 2) that appears in the code anywhere besides where assigned to a variable is a magic number and should instead be assigned to a const integer, enum, or macro. Likewise, any string literal (except "" and individual characters) that appears in the code anywhere besides where assigned to a char* or char[] is a magic string.

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

nomagicc

Fully implemented.

PRQA QA·CQA-C
Include Page
PRQA_V
PRQA_V
 Partially implemented

...

ISO/IEC 9899:2011 Section 6.3.2.1, "Lvalues, arrays, and function designators," section 6.7, "Declarations," section 6.7.2.2, "Enumeration specifiers," and section 6.10.3, "Macro replacement"

ISO/IEC TR 24772 "BRS Leveraging human experience"

MITRE CWE: CWE-547, "Use of hard-coded, security-relevant constants"

Bibliography

[Henricson 1992] Chapter 10, "Constants"
[Saks 2001a]
[Saks 2001b]
[Saks 2002]
[Summit 2005] Question 10.5b

...