0

Is there a difference between the following two approaches to defining a for-loop variable in C?

int i;
for (i = 0; i < X; i++) {
    // something
}

And:

for (int i = 0; i < X; i++) {
    // something
}

My preference is to use the second approach if the i is just always a throw-away, but is there any reason that it wouldn't be a good idea to do that?

13
  • I'd always go for the second, but in older versions of C, you can't do it. Commented Aug 23, 2019 at 20:16
  • 4
    Any decent compiler should produce the same code regardless of where you declare the variable. Commented Aug 23, 2019 at 20:23
  • 1
    If you step through the code for the second example you'll see that i is only getting declared and initialized once. If it was getting reinitialized every time, the loop would never exit! Commented Aug 23, 2019 at 20:27
  • 1
    The best way to understand this is to look at the assembly code that the compiler generates (-S for gcc or clang, or look at the assembly with a debugger). What you find (typically) is that the compiler reserves space for all of the variables at the beginning of the function, regardless of where the variables are declared. Even when variables are declared inside the loop body, the space for the variables is reserved at the top of the function. Commented Aug 23, 2019 at 20:33
  • 1
    @Shared The .s file is a text file that you can look at. It contains the output of the compiler in human-readable form. The .out file is the executable file. It is a binary file containing non-human-readable machine code. Commented Aug 23, 2019 at 20:52

3 Answers 3

2

Yes.

As the i variable is usually used only to count the number of iterations needed, it doesn't make sense to have a variable live outside the scope of the loop. That, if you can, should be avoided.

As some comments to the question mention, there are some cases in which you can't use the second, but that's not the general case.

As for the compiler later compiling to the same assembly, that may be true, but conceptually the second is cleaner, and for someone reading the code from outside, it makes it clear that the variable is never used again.

Hope this helps!

Sign up to request clarification or add additional context in comments.

Comments

1

but is there any reason that it wouldn't be a good idea to do that?

In C, you should prefer the second form, because it reduces the scope of the variable and makes it more obvious where it is going to be used. Unless...

  • ...it goes against the coding guidelines of a given project. For instance, the Linux kernel declares all variables at the top of a function.

  • ...you want to be conforming to C90: you cannot use loop initial declarations.

In C++, however, objects may have very expensive constructors, which means that, at times, you may want to re-use them rather than initialize a new one every time (e.g. if you construct a new one within the body of the loop).

7 Comments

What do object constructors have to do with declaring an integer counter inside or outside a loop? Seems like a totally different scenario unless I'm mistaken.
@ggorlen OP is asking about variables in general, not only integer counters.
There's no re-initializing "a new one every time" in either example OP provided though, they're both initialized once. The question is whether to declare out of a loop scope or do both inside the loop scope and makes no mention of C++.
@ggorlen He wasn't talking about initialization, he was talking about construction which, yes, can be expensive.
The title says that but the code doesn't. I take "within a loop" to be exactly what the code says, which is "within the initializer block of a for construct".
|
1

There are a number of differences between the two.

The second form is illegal in the 1989 ANSI (1990 ISO) C standard. The first is supported in C from 1999 and in standard C++. It is supported by some C compilers older than 1999, either as a non-standard or optional extension or because those compilers were actually C++ compilers with a C mode.

In the first form, i exists after the loop, so its value can still be accessed, but redefining it results in a diagnostic (compile time error). In the second form, i does not exist after the loop, so accessing its value after the loop gives a diagnostic, but i can be redefined.

In general terms, it is advisable to ensure that variables only exist for as long as needed, and cease to exist when no longer needed. The second form explicitly allows that.

Obviously, variables that need to exist outside the loop, need to be defined outside it. But, if the variable i is not needed outside the loop, then I would favour the second form. This allows the compilers to catch problems, such as unintended use of variable i after the loop.

Some older C and C++ compilers (mainly dating from before the 1998 C++ standard was ratified, but some from the early 2000s) implement the second form so the variable i still exists after the loop. This effectively makes the two forms equivalent when using those compilers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.