Versions Compared

Key

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

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 C programming language has several mechanisms for defining symbolic constants: const-qualified objects, enumeration constants, and macro definitions.

Objects that are const-qualified have scope and can be type-checked by the compiler. Because these are named objects (unlike macro definitions), (certain) debugging tools can show the name of the object. The objects also consumes memory (though this is not too important). Unfortunately, const-qualified objects cannot be used where compile-time integer constants are required, namely to define the

  • size of a bit-field member of a structure
  • size of an array (except in the case of variable length arrays)
  • value of an enumeration constant
  • value of a case constant

An enumeration constant is a member of an enumeration. Enumeration constant can be used to represent an integer constant expression that has a value representable as an int. Unlike const-qualified objects, enumeration constants do not require that storage is allocated for the value so it is not possible to take the address of an enumeration constant.

#define:

  • operates at compile time
  • consumes no memory (though this is not too important)
  • can use in compile-time constant expression
  • uses different syntax; can make mistake with ;
  • can't create pointers to
  • no type checking

const:

  • operates at run time
  • consumes memory (though this is not too important)
  • can't use in compile-time constant expression
  • uses consistent syntax
  • can create pointers to
  • does type checking

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

Method

Evaluated at

Consumes Memory

Viewable by Debuggers

Type Checking

Compile-time constant expression

Enumerations

compile time

no

yes

yes

no

const qualified

run time

yes

yes

yes

no

Macros

preprocessor

no

no

no

yes

Non-Compliant Code Example

...