[ACCEPTED]-Is there any overhead to declaring a variable within a loop? (C++)-variable-declaration
Stack space for local variables is usually 4 allocated in function scope. So no stack 3 pointer adjustment happens inside the loop, just 2 assigning 4 to var
. Therefore these two snippets 1 have the same overhead.
For primitive types and POD types, it makes 15 no difference. The compiler will allocate 14 the stack space for the variable at the 13 beginning of the function and deallocate 12 it when the function returns in both cases.
For 11 non-POD class types that have non-trivial 10 constructors, it WILL make a difference 9 -- in that case, putting the variable outside 8 the loop will only call the constructor 7 and destructor once and the assignment operator 6 each iteration, whereas putting it inside 5 the loop will call the constructor and destructor 4 for every iteration of the loop. Depending 3 on what the class' constructor, destructor, and 2 assignment operator do, this may or may 1 not be desirable.
They are both the same, and here's how you 11 can find out, by looking at what the compiler 10 does (even without optimisation set to high):
Look 9 at what the compiler (gcc 4.0) does to your 8 simple examples:
1.c:
main(){ int var; while(int i < 100) { var = 4; } }
gcc -S 1.c
1.s:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
2.c
main() { while(int i < 100) { int var = 4; } }
gcc 7 -S 2.c
2.s:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
From these, you can see two things: firstly, the 6 code is the same in both.
Secondly, the storage 5 for var is allocated outside the loop:
subl $24, %esp
And 4 finally the only thing in the loop is the 3 assignment and condition check:
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
Which is 2 about as efficient as you can be without 1 removing the loop entirely.
These days it is better to declare it inside 9 the loop unless it is a constant as the 8 compiler will be able to better optimize 7 the code (reducing variable scope).
EDIT: This 6 answer is mostly obsolete now. With the 5 rise of post-classical compilers, the cases 4 where the compiler can't figure it out are 3 getting rare. I can still construct them 2 but most people would classify the construction 1 as bad code.
Most modern compilers will optimize this 2 for you. That being said I would use your 1 first example as I find it more readable.
For a built-in type there will likely be 21 no difference between the 2 styles (probably 20 right down to the generated code).
However, if 19 the variable is a class with a non-trivial 18 constructor/destructor there could well 17 be a major difference in runtime cost. I'd 16 generally scope the variable to inside the 15 loop (to keep the scope as small as possible), but 14 if that turns out to have a perf impact 13 I'd look to moving the class variable outside 12 the loop's scope. However, doing that needs 11 some additional analysis as the semantics 10 of the ode path may change, so this can 9 only be done if the sematics permit it.
An 8 RAII class might need this behavior. For 7 example, a class that manages file access 6 lifetime might need to be created and destroyed 5 on each loop iteration to manage the file 4 access properly.
Suppose you have a LockMgr
class 3 that acquires a critical section when it's 2 constructed and releases it when destroyed:
while (i< 100) {
LockMgr lock( myCriticalSection); // acquires a critical section at start of
// each loop iteration
// do stuff...
} // critical section is released at end of each loop iteration
is 1 quite different from:
LockMgr lock( myCriticalSection);
while (i< 100) {
// do stuff...
}
Both loops have the same efficiency. They 3 will both take an infinite amount of time 2 :) It may be a good idea to increment i 1 inside the loops.
I once ran some perfomance tests, and to 9 my surprise, found that case 1 was actually 8 faster! I suppose this may be because declaring 7 the variable inside the loop reduces its 6 scope, so it gets free'd earlier. However, that 5 was a long time ago, on a very old compiler. Im 4 sure modern compilers do a better job of 3 optimizing away the diferences, but it still 2 doesn't hurt to keep your variable scope 1 as short as possible.
#include <stdio.h>
int main()
{
for(int i = 0; i < 10; i++)
{
int test;
if(i == 0)
test = 100;
printf("%d\n", test);
}
}
Code above always prints 100 10 times which 2 means local variable inside loop is only 1 allocated once per each function call.
The only way to be sure is to time them. But 9 the difference, if there is one, will be 8 microscopic, so you will need a mighty big 7 timing loop.
More to the point, the first 6 one is better style because it initializes 5 the variable var, while the other one leaves 4 it uninitialized. This and the guideline 3 that one should define variables as near 2 to their point of use as possible, means 1 that the first form should normally be preferred.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.