My instructor once told me that I should not define a variable inside a loop, but I honestly still do not understand why.
What are the disadvantages of that?
Could any body explain that to me?
My instructor once told me that I should not define a variable inside a loop, but I honestly still do not understand why.
What are the disadvantages of that?
Could any body explain that to me?
It's not a problem to define a variable within a loop. In fact, it's good practice, since identifiers should be confined to the smallest possible scope.
What's bad is to assign a variable within a loop if you could just as well assign it once before the loop runs. Depending on how complex the right-hand side of the assignment is, this could become rather expensive and might even dominate the run time of the loop. If you write a loop that uses the same computed value in all iterations, you should definitely compute it above the loop - that is more important than minimizing its scope.
To clarify: as long as compute()
always returns the same value, this
int value = compute();
while (something) {
doSomething(value);
}
is smarter than this:
while (something) {
int value = compute();
doSomething(value);
}
Complex types have non-trivial constructors and destructors.
Those will get called at the start and end of the loop body (as it's initialized and goes out of scope). If the initialization is expensive like it needs to allocate some memory then that should be avoided.
However for trivial types that is no problem. The allocation and deallocation itself is just adding and subtracting a value from the stack pointer. (which will get optimized out)
Well, his advice is slightly too simple (that's an understatement).
Following it ranges all the way from a good idea over who cares and bad idea to impossible.
You should follow it whenever re-using is cheaper than destroying the old and creating a new one.
#include <iostream>
#include <string>
int main() {
std::string s; // Don't needlessly free the buffer
while ((std::cin >> s))
std::cout << s;
}
You should shun it as a matter of style when it doesn't matter for performance.
#include <stdio.h>
#include <stdlib.h>
int f(int, int);
int main() {
for (int i = 0; i < 100; ++i) {
int x = rand(); // Declared here so you don't need to hunt it down.
printf("%d => %d\n", x, f(x-1, x+i));
}
}
You really should shun it when it has worse performance or the wrong semantics.
#include <iostream>
#include <string>
std::string generate(int);
int main() {
for(int i = 0; i < 100; ++i) {
std::string s = generate(i); // Using copy-ellision here
std::cout << s;
}
}
You cannot follow it when the used type allows neither swapping, nor move-assignment nor copy-assignment.
#include <iostream>
#include <puzzle>
int main() {
for (int i = 0; i < 100; ++i) {
Puzzle x(i); // Puzzle is an immutable class. For whatever reasons.
std::cout << x;
}
}