Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a 'for' loop iterator after the loop exits in C

Tags:

c

for-loop

c99

For years, I've gotten in to the habit of not using the value of a for loop iterator after the loop exits. I could have sworn that I did this, because it used to produce a compiler warning, but after I was challenged in a recent code review, I was proven wrong.

For example, I always did this (NOTE: our code standards prohibit the use of the "break" keyword):

int i, result;
bool done = false;
for (i=0; i<10 && !done; i++) {
    if (some_condition) {
        result = i;
        done = true;
    }
}
// Value of i may be undefined here

Now, obviously the result variable could be removed, if I can rely on the value of i. I thought that because of compiler optimization, you could not rely on the value of the loop iterator. Am I just remembering a phantom teaching? Or is this the standard (specifically regarding GNU C)?

like image 809
David Dombrowsky Avatar asked May 01 '12 14:05

David Dombrowsky


People also ask

Is it possible to use a for loop iterator after the loop?

In C there is nothing wrong with using the (properly scoped) for loop iterator after the loop is complete. Unless /* some code */ is replaced by break; In that case, the variable i would contain the value 0 (i++ is not executed after break). While it's possible, doesn't mean it's good practice.

How to exit a loop in C++?

Some common ways to exit a loop are as follows: Break: This statement is a loop control statement used to terminate the loop. Below is the C++ program to illustrate the use of the break statement:

What are iterative statements in C?

Iteration statements are most commonly know as loops. Also the repetition process in C is done by using loop control instruction. There are three types of looping statements:

What is iteration in C programming?

Iteration is the process where a set of instructions or statements is executed repeatedly for a specified number of time or until a condition is met. These statements also alter the control flow of the program and thus can also be classified as control statements in C Programming Language. Iteration statements are most commonly know as loops.


3 Answers

There is nothing wrong in C89, C99, or C11 to access the iteration variable after the for statement.

 int i;

 for (i = 0; i < 10; i++) {
     /* Some code */
 }

 printf("%d\n", i);  // No magic, the value is 10

From C99, you can use also a declaration as the first clause of the for statement, and in that case of course the declared variable cannot be used after the for statement.

like image 98
ouah Avatar answered Oct 16 '22 21:10

ouah


Different languages have different rules. In Pascal, the compiler is allowed to optimize away storing the loop index after the final increment, so it might be the first loop-terminating value or it might be the last valid value.

like image 39
DutchUncle Avatar answered Oct 16 '22 20:10

DutchUncle


There are plenty of usage cases where the for loop is used for nothing else but advancing the iterator. This can be seen in some implementations of strlen (though admittedly there are other ways to do strlen), and other sorts of functions whose goal it is to find a certain limit:

/*find the index of the first element which is odd*/
for (ii = 0; ii < nelem && arry[ii] % 2 == 0; ii++);

As mentioned, the point of confusion may come from constructs where the iterator itself is defined within the for statement.

In general for statements are very very powerful, and it's unfortunate that they're usually never utilized to their full potential.

For example, a different version of the same loop can be written as follows (though it wouldn't demonstrate the safety of using the iterator):

#include <stdio.h>
int main(void)
{
    int cur, ii = 0, nelem, arry [] = { 1, 2, 4, 6, 8, 8, 3, 42, 45, 67 };
    int sum = 0;

    nelem = sizeof(arry) / sizeof(int);
    /* Look mom! no curly braces! */

    for (
            ii = 0;
            ii < nelem && ((cur = arry[ii]) %2 == 0 ||
                                ((printf("Found odd number: %d\n", cur)||1)));
            ii++, sum += cur
        );
    printf("Sum of all numbers is %d\n", sum);
    return 0;
}

In this particular case, it seems like a lot of work for this specific problem, but it can be very handy for some things.

like image 32
Mark Nunberg Avatar answered Oct 16 '22 20:10

Mark Nunberg