Search code examples
cfor-loopc99c89

Is there any benefit to declaring the counter outside of the for loop body in C99?


I'm familiar with C++ and I've recently decided to learn C. The tutorial that I'm following often writes for loops like this:

int i;

for (i = 0; i < 5; i++)
{
    printf("%d", i);
}

You can see that the counter (i) is declared outside of the for loop body. When writing it in C (and C++) I write:

for (int i = 0; i < 5; i++)
{
    printf("%d", i);
}

I've researched this a bit and it seems like the latter was illegal in C89 and was only introduced in C99. However, the tutorial I'm using is based on C99 and I've also seen a lot of modern C code where the counter is still declared outside of the for loop body.

Therefore, the question that I'm asking is: is there any practical benefit to declaring the counter outside of the for loop body in C99? In other words, which way should I write it?

Note: I've seen that there's "similar questions" but most of them are asking why the counter is declared outside of the for loop body in some code rather than whether there's any benefit. With that being said, there was one similar question that was asking about the benefit but it was in C++ and I'm not sure if there's a difference between the two languages in this regard.


Solution

  • The main benefits in declaring the loop counter before the for statement are:

    • portability to pre-C99 compilers,
    • access to this variable beyond the end of the for loop.

    If defined before the for statement, this variable is still valid and in scope after the loop, which may be very useful if the loop was exited via a break statement:

    void foo(void) {
        int i;
        for (i = 0; i < 100; i++) {
            if (bar(i))
                break;
        }
        ...
        if (i != 100) {
            printf("loop was exited after %d calls\n", i + 1);
        }
    }
    

    The downside is you cannot reuse the same identifier for another loop later in the same scope with a different type.

    If you don't need to access the loop counter after the for statement, declaring it in the first clause of the for statement improves readability and maintainability.

    Conversely, it you need portability back to pre-C99 compilers, you should avoid C99-specific features such as this one.