Rules:
8.4.a. Magic numbers shall not be used as the initial value or in the endpoint test of a while, do…while, or for loop.14
8.4.b. With the exception of the initialization of a loop counter in the first clause of a for statement and the change to the same variable in the third, no assignment shall be made in any loop’s controlling expression.
8.4.c. Infinite loops shall be implemented via controlling expression for (;;).15
8.4.d. Each loop with an empty body shall feature a set of braces enclosing a comment to explain why nothing needs to be done until after the loop terminates.
Example:
// Why would anyone bury a magic number (e.g., “100”) in their code?
for (int row = 0; row < 100; row++)
{
// Descriptively-named constants prevent defects and aid readability.
for (int col = 0; col < NUM_COLS; col++)
{
...
}
Reasoning: It is always important to synchronize the number of loop iterations to the size of the underlying data structure. Doing this via a descriptively-named constant prevents defects that result when changes in one part of the code, such as the dimension of an array, are not matched in other areas of the code.
Enforcement: These rules shall be enforced during code reviews.
Footnotes
[14] Note that the sizeof macro is a theoretically handy way to dimension an array but that this method does not work when you pass a pointer to the array instead of the array itself.
[15] Kernighan & Ritchie long ago recommended for (;;) , which has the additional benefit of insuring against the visually-confusing defect of a while (l); referencing a variable ‘l’.