Declaring static and non-static variables inside loops

Viewed 492

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 Answers

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.

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.

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.

Related