14

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?

closed as unclear what you're asking by GlenH7, durron597, Bart van Ingen Schenau, gnat, Ixrec Sep 8 '15 at 19:43

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 7
    What programming language was your instructor teaching? – Brian Sep 8 '15 at 14:35
  • 2
    If you define a variable with a non-primitive type in a loop, your program might end up needlessly calling its constructor every time through the loop. If you only need to define it once outside the loop, do that. – Brandin Sep 8 '15 at 14:41
  • 17
    When you have such confusion about what an instructor says, the best resource is asking the instructor. They can give you the dense back and forth communication that a Q&A site cannot provide. – user40980 Sep 8 '15 at 14:54
  • 1
    Cross-site duplicate: Difference between declaring variables before or in loop? (and of course many, many duplicates on that site for such an elementary question (including the ones that are only about C++)). – Peter Mortensen Sep 8 '15 at 19:49
  • 2
    That advice was specific to a context. As a matter of personal style, I prefer to declare my variables const unless there’s a reason not to (a habit from functional programming). Either I won’t modify them, and the optimizer should detect when they aren’t needed, or I will and I’ve prevented a serious bug. When those constant intermediate values are specific to an iteration of the loop, that means declaring them inside the loop. Another time when you need to declare variables outside the loop, though, is when you’ll refer to them outside the loop; for example, the results you’re storing. – Davislor Sep 8 '15 at 20:38
41

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);
}
  • 2
    How would you define a variable in the loop and assign it before the loop? – Masked Man Sep 8 '15 at 16:27
  • 6
    @MaskedMan, I think you're misunderstanding. What Kilian meant is if you have a variable that is assigned the same value during each iteration of a loop, e.g., the same date variable is set to 1/1/1900, the variable should be declared and the value should be assigned prior to the loop. – ps2goat Sep 8 '15 at 16:36
  • 2
    I don't think there's been a compiler written in the last twenty years (outside of an undergrad compiler course) that wouldn't figure out you're assigning the same value on each iteration and move that assignment out of the loop. – TMN Sep 8 '15 at 18:41
  • 14
    @tmn: Never let a compiler do what you can trivially do yourself with greater code clarity. – Robert Harvey Sep 8 '15 at 19:09
  • 10
    @TMN, not necessarily. That optimization is only possible if the compiler can prove that the computation is side-effect free. – Paul Draper Sep 8 '15 at 19:26
16

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)

  • thanks, exactly the answer I was looking for! – gebbissimo Jun 25 at 15:52
6

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.

  1. 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;
    }
    
  2. 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));
        }
    }
    
  3. 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;
        }
    }
    
  4. 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;
        }
    }
    
  • 2
    Depending on your definition of "in a loop", 1 can be changed to for (std::string s; std::cin >> s;) ... and still be "outside" – Caleth Feb 16 '18 at 10:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.