Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

At what exact moment is a local variable allocated storage?

Suppose we have the following:

void print()
{
     int a;  // declaration
     a = 9;
     cout << a << endl;
}

int main ()
{
     print();
}

Is the storage for variable a allocated at the moment function print is called in main or is it when execution reaches the declaration inside the function?

like image 903
Brandon Tiqui Avatar asked Mar 01 '10 05:03

Brandon Tiqui


1 Answers

This is very much compiler dependent under the covers, but logically the storage is assigned as soon as the variable is declared.

Consider this simplistic C++ example:

// junk.c++
int addtwo(int a)
{
    int x = 2;

    return a + x;
}

When GCC compiles this, the following code is generated (; comments mine):

.file   "junk.c++"
    .text
.globl _Z6addtwoi
    .type   _Z6addtwoi, @function
_Z6addtwoi:
.LFB2:
    pushl   %ebp           ;store the old stack frame (caller's parameters and locals)
.LCFI0:
    movl    %esp, %ebp     ;set up the base pointer for our parameters and locals
.LCFI1:
    subl    $16, %esp      ;leave room for local variables on the stack
.LCFI2:
    movl    $2, -4(%ebp)   ;store the 2 in "x" (-4 offset from the base pointer)
    movl    -4(%ebp), %edx ;put "x" into the DX register
    movl    8(%ebp), %eax  ;put "a" (+8 offset from base pointer) into AX register
    addl    %edx, %eax     ;add the two together, storing the results in AX
    leave                  ;tear down the stack frame, no more locals or parameters
    ret                    ;exit the function, result is returned in AX by convention
.LFE2:
    .size   _Z6addtwoi, .-_Z6addtwoi
    .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    .section    .note.GNU-stack,"",@progbits

Everything between _Z6addtwoi and .LCFI2 is boilerplate code used to set up the stack frame (store the previous function's variables, etc. safely out of the way). That last "subl $16, %esp" is the allocation of the local variable x.

.LCFI2 is the first bit of actual executing code that you've typed. "movl $2, -4(%ebp)" is putting the value 2 into the variable. (Initialization, in other words.) Now your space is allocated AND initialized. After that it loads the value into register EDX and follows that by moving your parameter, found in "8(%ebp)", into another register EAX. It then adds the two together, leaving the result in EAX. This is now the end of any code you've actually typed. The rest is again just boilerplate. Since GCC mandates that integers are returned in EAX, no work has to be done for the return value. The "leave" instruction tears down the stack frame and the "ret" instruction returns control back to the caller.

TL;DR summary: you can think of your space as having been allocated with the very first line of executable code in your block (paired {}).


I thought I'd clean this up a bit with explanatory comments seeing as this is the selected answer.

like image 91
JUST MY correct OPINION Avatar answered Sep 28 '22 05:09

JUST MY correct OPINION