Home > OS >  Life cycle of a variable
Life cycle of a variable

Time:02-15

I am not clear for how long a variable is guaranteed to be allocated in C.

For example, if I have:

void foo(void) {
  int x;
  int* y = &x;
  ...
}

Is the space allocated on the stack for x guaranteed to be reserved for this variable exclusively for the entire duration of foo()? Said differently, is y guaranteed to point to a location that will be preserved for the entire duration of foo, or could the compiler decide that since x isn't being used, the stack space can be used for another use within foo and therefore *y may change without accessing y (or x) directly?

CodePudding user response:

When you ask questions like this, you should be clear whether you are asking about C semantics or about program implementation.

C semantics are described using a model of an abstract computer in which all operations are performed as the C standard describes them. When a compiler compiles a program, it can change how the program is implemented as long as it gets the same results. (The results that must be correct are the observable behavior of the program: its output, including data written to files, its input/output interactions, and its accesses to volatile objects.)

In the abstract computer, memory for x is reserved from the time an execution of foo starts until that execution of foo ends.1, 2

So, in the abstract computer, it does not matter if x is used or not; memory is reserved for it until foo returns or its execution is ended in some other way (such as a longjmp or program termination).

When the compiler implements this program, it is allowed optimize away x completely (if it and its address are not used in any way that requires the memory to be reserved) or to use the same memory for x that it uses for other things, as long as the uses do not conflict in ways that change the observable behavior. For example, if we have this code:

int x;
int *y = &x;
x = 3;
printf("%d\n", x);
int b = 4;
printf("%d\n", b);

then the compiler may use the same memory for b that it uses for x.

On the other hand, if we have this code:

int x;
int *y = x;
printf("%p\n", (void *) y);
int b = 4;
printf("%p\n", (void *) &b);

then the program must print different values for the two printf statements. This is because different objects that both exist at the same moment in the abstract computer model must have different addresses. The abstract computer would print different addresses for these, so the compiler must generate a program that is faithful to that model.

Footnotes

1 There can be multiple executions of a function live at one time, due to nested function calls.

2 Sometimes people say the lifetime of x is the scope of the function, but this is incorrect. The function could call another routine and pass it y, which has the address of x. Then the other routine can access x using this address. The memory is still reserved for x even though it is not in the scope of the other routine’s source code. During the subroutine call, the execution of foo is temporarily suspended, but it is not ended, so the lifetime of x has not ended.

CodePudding user response:

The lifetime of an automatic variable is the entire duration of the scope in which it is declared; in your case, that scope is the whole of the foo function.

Compilers are allowed to make optimizations (including removing variables completely) that can have no possible observable effect; however, once you assign the address of x to y, then any use of *y will be using x, so the memory allocated for x cannot then be used for something else, all the time there is a possibility of accessing or modifying *y.

CodePudding user response:

x is being used, y is being passed the address of it! In short the answer is "yes" as long as the compiler author(s) is(are) sensible. Most compilers ( visual studio at least ) wouldn't compile this or at least warn that x is uninitialized so this isn't a very realistic example.

Y most definitely cannot change by changing another variable than x or y. that's 100%. When you go into a function the parameters then the local variables are pushed onto the stack and then when you come out of a function they are popped off. There is no scope for shared memory (unless you are using a union).

Whats the reason behind this question? If you really want to know how c is defined you should read "The C Programming Language" by Kernighan and Ritchie"

  • Related