在什么时刻是本地变量分配存储?

Bra*_*don 9 c++ memory-management

假设我们有以下内容:

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

int main ()
{
     print();
}
Run Code Online (Sandbox Code Playgroud)

是否在函数print中分配的变量a的存储是在main中调用还是在执行到达函数内部的声明时?

JUS*_*ION 9

这在很大程度上取决于编译器,但逻辑上,一旦声明了变量,就会分配存储.

考虑这个简单的C++示例:

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

    return a + x;
}
Run Code Online (Sandbox Code Playgroud)

当GCC编译它时,会生成以下代码(;我的评论):

.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
Run Code Online (Sandbox Code Playgroud)

_Z6addtwoi和.LCFI2之间的所有内容都是用于设置堆栈帧的样板代码(安全地存储前一个函数的变量等).最后一个"subl $ 16,%esp"是局部变量x的分配.

.LCFI2是您键入的实际执行代码的第一位."movl $ 2,-4(%ebp)"将值2放入变量中.(换句话说,初始化.)现在,您的空间已分配并初始化.之后,它将值加载到寄存器EDX中,然后将"8(%ebp)"中的参数移动到另一个寄存器EAX中.然后将两者加在一起,将结果保留在EAX中.现在,这是您实际输入的任何代码的结尾.剩下的只是样板.由于GCC要求在EAX中返回整数,因此不必对返回值进行任何操作."离开"指令拆除堆栈帧,"ret"指令将控制权返回给调用者.

TL; DR摘要:您可以将您的空间视为已使用块中的第一行可执行代码进行分配(配对{}).


我想我会用解释性评论清理一下,因为这是选定的答案.