The address of `a` (a variable inside the loop) not changing

105 views Asked by At

Here is the C code snippet.

#include<stdio.h>

int N = 10;
while (N--) {
    int *a;
    printf("%p\n", &a);
}

The running results(Compiler: tdm-gcc 4.9.2 64-bit release, os: win11 ) show that the program prints the same value in N loops. Is this a random event, or is it caused by some mechanism in the C language?

2

There are 2 answers

0
Remy Lebeau On

a is a local variable inside of the loop body. You are printing the address of the variable itself, not the address it is pointing at. The variable enters and leaves scope on each loop iteration, and when it goes out of scope its memory becomes available for reuse. So, when one iteration is finished, the compiler is allowed to reuse that same memory on the next iteration for the same variable, if it wants to. But this is not a guarantee, so don't rely on it.

0
John Bode On

Per the rules of the abstract machine, a only exists within the body of the loop and a new instance of a is created for each loop iteration:

6.2.4 Storage durations of objects

1 An object has a storage duration that determines its lifetime. There are four storage durations: static, thread, automatic, and allocated. Allocated storage is described in 7.22.3.

2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,33) and retains its last-stored value throughout its lifetime.34) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

...

5 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals. The result of attempting to indirectly access an object with automatic storage duration from a thread other than the one with which the object is associated is implementation-defined.

6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

C 202x Working Draft

However, common practice in most compilers is to generate code that allocates storage for a once at function entry and reuses that storage for every loop iteration. Most compilers will do some analysis to determine how much storage is necessary to handle all locals and block-scope variables and allocate it up front.

Most is not all, though, and such behavior isn't guaranteed.