Giving Names to Numeric Literals [VU1]
Tip VU1
Numbers are one of the most common kinds of literals in code that can benefit from being assigned names.
Consider the following example:
Numeric Literals That May Be Self-Documenting in Limited Circumstances
Replacing numeric literals with well-named constants is a good practice that helps eliminate doubt in the meaning of numeric literals. However, there are a few circumstances where direct usage of numeric literals may be self-documenting enough to be acceptable:
Using
0
as the starting index for loop iteration or another initial value for a variable.Using
0
to check if something's empty (or similar greater/less than comparisons).Using
1
to check if something's populated with a "single" value (or if a "count" of something is specifically single).Using
1
in increment/decrement operations.Using
2
to double or half something.
When indexing into a container/collection, it's still often better to have a constant over a magic number (even if just accessing something like the first element in a container/collection). Such a constant can communicate the intent of the element you’re trying to access.
Even if a situation falls underneath one of the "acceptable" cases above, it still might be better to use a named constant. For example, consider the following:
char name[NAME_LENGTH + 1] = { 0 };
The meaning of the + 1
might be recognizable to many C programmers, but even then, the intended meaning is uncertain. The following introduces an additional named constant to clarify the intent:
constexpr std::size_t NULL_TERMINATOR_CHARACTER_COUNT = 1;
char name[NAME_LENGTH + NULL_TERMINATOR_CHARACTER_COUNT] = { 0 };
So even if using a numeric literal might be acceptable in some cases, think very deeply if there is a name you could assign to a literal that would communicate problem domain understanding.