Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

The C language provides several different kinds of constants: integer constants, such as 10 and 0x1C; floating constants, such as 1.0 and 6.022e+23; and character constants, such as 'a' and '\x10'. C also provides string literals, such as "hello, world" and "\n". These can all be referred to as literals.

Wiki MarkupWhen 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 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|AA. Bibliography#Saks 02]\].

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.

...

Code Block
const int max = 15;
int a[max]; /* invalid declaration outside of a function */
const int *p;

/* a const-qualified object can have its address taken */
p = &max;

Wiki Markup{{const}}\-qualified objects are likely to incur some runtime overhead \ [[Saks 2001b|AA. Bibliography#Saks 02]\]. 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.

Enumeration Constants

Enumeration constants 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 consume memory. No storage is allocated for the value, so it is not possible to take the address of an enumeration constant.

...

# define identifier replacement-listunmigrated-wiki-markup

defines an _object-like_ macro that causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive \[ [ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\].

C programmers frequently define symbolic constants as object-like macros. For example, the code

...

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|AA. Bibliography#Saks 02]\]. 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 recommendation ARR01-C. Do not apply the sizeof operator to a pointer when taking the size of an array.

...

Tool

Version

Checker

Description

Section

LDRA tool suite

Include Page
c:LDRA_Vc:
LDRA_V
Section

201 S

Section

Fully Implemented

Section

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 (besides a few canonical numbers: \ -1, 0, 1, 2) that appears in the code anywhere besides being 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 being assigned to a {{char\*}} or {{char\[\]}} is a magic string.\\

Section

Wiki Markup
Section

ECLAIR

Include Page
c:ECLAIR_Vc:
ECLAIR_V
Section

nomagicc

Section

Fully Implemented

...

MITRE CWE: CWE-547, "Use of Hard-coded, Security-relevant Constants"

Bibliography

Wiki Markup\[[Henricson 1992|AA. Bibliography#Henricson 92]\] Chapter 10, "[Constants|http://www.doc.ic.ac.uk/lab/cplus/c++.rules/chap10.html]" \[[Saks 2001a|AA. Bibliography#Saks 01]\] \[[Saks 2001b|AA. Bibliography#Saks 02]\] \[[Saks 2002|AA. Bibliography#Saks 02]\] \[[Summit 2005|AA. Bibliography#Summit 05]\] [Question 10.5b|http://c-faq.com/cpp/constvsdefine.html]"
[Saks 2001a]
[Saks 2001b]
[Saks 2002]
[Summit 2005] Question 10.5b

...

DCL05-C. Use typedefs to improve code readability      02. Declarations and Initialization (DCL)