I ask this question mostly in regards to C programming, but insights on any language are welcome.
When it comes to C, I know it only lets variable declarations occur at the very beginning of a block of code. And I have been under the impression that one should declare all variables to be used within a function at the very beginning of the function. But there are many occasions where I'll have a variable that is only used within a loop (or similar block).
an example would be a temporary variable for some return value:
while ( whatever ) {
int ret;
ret = getSomeValue();
}
or where some state may need to be held:
while ( whatever ) {
static int count=0;
count++;
}
I was wondering if it is considered improper, or, if there is any negative impact to declaring variables within control flow blocks such as if-else, for loops, while loops, etc.
Should variables always be declared with the tightest possible scope? what about for static declaration?
Edit:
Okay, I probably should have said I'm aware C99 is more liberal when it comes to where you declare variables, but from a lot of C code I see, they're still usually declared at top. Also, I use VS2K8 which still complains about declarations.
Also, seeing as I've had 2 votes to close this thead, I'll make it clear that I'm more concerned with the performance and compiler aspects than I am with anything stylistic.
A rule of thumb is that variables should always be made as local as possible. Bonus points if you can make it const
.
Ok, the thing about declarations at the top of blocks is C89 and K&R, but since C99 you can mix declarations and statements. The style persists, probably for good reasons, but it's not required.
There was a time when some compilers would do a better job if you declared lots of local variables right where they were used, because it made register allocation better. Pre-C99, you had to declare them at the top of blocks or use a vendor-extension, but you could still decide to actually use each variable only in a local area of code.
It probably seemed important at one point to directly support this with more flexible declaration placement, but I suspect that these days the optimizers don't need that kind of help.
Some coding standards require declarations at the top of functions. I don't know if this is so you can find them or if it's just left over from the days where not doing that might limit backwards portability.
In general, the more formal the standard, the less it likes interleaving statements and declarations, except for loop control variables. Personally, I don't see the problem with it.
Advantages of mixed declarations: locality. Good for the compiler, good for the reader. What possible benefit can accrue from declaring a loop variable at the top of a function? Reusing a variable down the page for an unrelated purpose seems confusing and unwise in terms of possible unwanted interactions.
Advantages of grouped declarations: the code looks cleaner in a subjective way, you know where to go to find every declaration, and if the top of your function is too far away from the use of the variable, perhaps that's telling you that you need to extract a second or third function from the obviously too-big one.
Where you declare a variable doesn't affect the code generation. All a functions variables a put on the stack before the first line of code even gets executed (at least this is observed behavior). As you already know, the rules about variable declaration a long dead. Declaring variables at the top has these advantages
- easier to read, when all variables can be found in the same place
- you don't need to worry about rearranging code if you need to suddenly access a variable before it is declared (unless of course, you purposely want to prevent this).
And yes, I would make variables as local as possible. If a variable is used only within a loop or control flow or even a meaningless {} pair (Which I have used to prevent name clashing), then declare them there. Take the famous n or i variable in for loops. If you have multiple, you will need a unique var name for each for loop, which would become annoying.