4
votes

I want to use a variable inside a loop, but I don't want it to be re-declared on every iteration. Obviously I can declare it outside of the loop but I wondered what would happen if I declared it as static inside the loop.

To test this I declared both a static and a non-static variable inside a while loop and printed their memory addresses on each iteration. I expected the address of the non-static variable to keep changing and that of the static to stay the same.

  while (true)
  {
    int var1;
    static int var2;

    cout << &var1 << "\n"
         << &var2 << endl;
  }

Results: To my surprise the addresses of both variables stayed the same.

  1. Is this some kind of compiler optimization or was I wrong to assume that re-declaring the non-static variable should yield a different address on every iteration? I'm using gcc 9.3.0 with no optimization flags.
  2. Is the static variable a good alternative to declaring a non-static variable outside of the loop (assuming I won't need it in the outer scope and I'm not concerned that the variable will retain its last value in case the loop is entered again at a later time)?
3
Regarding "good alternative": depends on what you need the variable for. How are you going to use it? Do you have anything specific in mind?anatolyg
Try putting the shown code inside a different function, and then call it directly from main and from another function (that is called by main). Then you should see a difference.Some programmer dude
@Someprogrammerdude The difference is of scope and that the variable will start with its last value when it enters the loop a second time. I get that, but would there be any other concerns?Windom Earle
Not scope, but life-time. Both var1 and var2 have the exact same scope. The static storage duration of var2 means that its life-time will be the whole programs full run-time. Local static variables are also guaranteed to be zero-initialized, unless explicitly initialized some other way, and also the initialization (and only initialization) is guaranteed to be thread-safe and happen only once.Some programmer dude
The static option is going to add some synchronisation to the code as function static objects are guaranteed to only be initialised once in multi-threaded code.Richard Critten

3 Answers

2
votes

The non-static variable gets created and destroyed on each iteration of the loop.

It just so happens that it gets created, every time, on the same memory address.

However, relying on this, and relying on the variable's contents getting preserved across loop iterations will be undefined behavior.

1
votes

Expecting the compiler to change the address of the local variable is not reasonable: there is only a limited number of possible addresses (264) but your loop is infinite, so the address would have to repeat somehow. And the easiest way to repeat is to repeat immediately.

Regarding whether static is good enough - depends on the usage. However, static is probably not better than local for most usages, otherwise static would be the default behavior.

0
votes

The static variable obviously only gets initialized once so it is perfectly reasonable to expect the address to stay the same.

Now, for the non-static variable. When a variable is declared inside a loop, it will be destroyed before the next iteration of the loop. This means that the memory will be available again the next time the loop runs. Therefore, the variable would likely have the same address.

In fact, the compiler probably has to do this because it has no way of knowing how many times the loop will run. Since computers only have finite memory, we cannot allocate a new variable at each iteration.

One way to think about it is that the variable is actually created outside the loop. In fact, some languages (e.g. Pascal) actually require you to declare all variables at the beginning of a function. It's just that declaring variables inside loops reduce the cognitive load a bit which is why most languages support it. But in the end, it all comes down to the same thing.