Reputation: 133
Say I have a function like this :
int myfunc()
{
int a;
// do something
int b;
// do something
}
when I call myfunc() does the memory allocation for b occur right after a ? Or is b created after the first "do something" is done.
Upvotes: 1
Views: 192
Reputation: 133919
First of all, the standard does not use the term constructed. Variables are defined and initialized and assigned to, but not constructed. A definition asks the compiler to reserve memory for the variable.
The standard says that the variables with automatic storage duration have a lifetime that extends from entry to the block until the execution of the block ends in any way. They are initialized when the corresponding line is executed. During its lifetime an object will have memory reserved for it and it will reside at a fixed address.
Given a program
#include <stdio.h>
int main(void) {
int a = 0;
foo:;
int b = 42;
print("%d %d\n", a, b);
a ++;
b ++;
goto foo;
}
b
will have a constant address for the entire duration of the main
function, and so does a
, but b
is reinitialized after every goto
.
However the standard also says that an implementation need not produce an executable that does things as set in the standard for as long as the external behaviour of the executable is as if the program was translated according to the text of standard. This is known as the as-if rule. For example if you do not observe them having memory reserved for them, or you do not observe their address, then compiler need not necessarily reserve memory for them.
For example if you have the following program:
#include <stdio.h>
int main(void) {
int a = 0;
for ( ; a < 3; a++) {
printf("*");
}
}
and you ask "when is memory reserved for a
", then know that both GCC and Clang will, with -O3, compile this to an executable whose machine code is equivalent to that of
#include <stdio.h>
int main(void) {
putchar('*');
putchar('*');
putchar('*');
}
Now, when did a
get "constructed"?
Upvotes: 5
Reputation: 19221
The C standard doesn't say a thing about this and leaves this to be a system specific implementation detail.
Also, compilers are free to optimize the variables away, place them in registers (rather than memory) or do whatever they want as long as the logic implied by your C program runs as intended (meaning you can't tell the difference).
In practical terms, on most systems (but not all systems), these variable aren't really "allocated" at all - at least not in the normal sense.
These variables live on the "stack", which is often (but not always) a single allocation performed right before execution begins for the thread.
The variables (if not optimized away) represent part of the function's stack "frame", so every time the function is called it will reserve sizeof(int) * 2
for itself as part of its stack frame.
It's like a stack of dishes in the kitchen. Whenever you call a function, you place it on top of the stack. When a function returns, it (and everything above it) is removed from the stack.
My explanation is so simplified here that it could be considered wrong, but it's close enough to what's happening for you to get the idea (I hope).
You can read more detailed information on Wikipedia or various internet resources such as this one.
Upvotes: 3