parts/6.29.LoopControlVariables-TEX.md

6.29 Loop Control Variables [TEX]

6.29.1 Applicability to language

The vulnerability as described in ISO/IEC TR 24772-1:2019 clause 6.29 exists in C++.

C++ allows the modification of loop control variables within non range-based loops. This is usually not considered good programming practice as it can cause unexpected problems. The flexibility of C++ expects the programmer to use this capability responsibly.

Since the modification of a loop control variable within a loop is infrequently encountered, reviewers of C++ code may not expect it and hence miss noticing the modification. Modifying the loop control variable can cause unexpected results if not carefully done. In C++, the following is semantically correct, but is error-prone:

int a;
for (int i = 1; i < 10; i++){
    ...
    if (a > 7)
        i = 10;
    ...
}

which will cause the for loop to exit once a is greater than 7 regardless of the number of iterations that have occurred.

for (int i : std::ranges::iota_view{1,10})
{
    if (a > 7) {
       i = 10;   // This changes the local variable for this loop iteration's execution
                 // but subsequent iterations are not affected
       }
    }
    
for (int const i : std::ranges::iota_view{1,10})
{
    if (a > 7) {
       i = 10;   // This is now illegal since the 'const int' prevents assign
       }
    }

The range for example immediately above does not have the vulnerability of the C-like for loop above.

for (int i=1; i < 10; ++i) ...

In a range-based for loop, the control variable is not available.

std::array a {3, 1, 4, 1, 5};
for (auto const x : a) {
    std::cout << x << '\n';
}

6.29.2 Avoidance mechanisms for language users

To avoid the vulnerability or mitigate its ill effects, C++ software developers can:

Note: See also the C++ Core Guidelines ES.71, ES.86.