In C, do braces act as a stack frame?

2019-01-04 22:18发布

If I create a variable within a new set of curly braces, is that variable popped off the stack on the closing brace, or does it hang out until the end of the function? For example:

void foo() {
   int c[100];
   {
       int d[200];
   }
   //code that takes a while
   return;
}

Will d be taking up memory during the code that takes a while section?

标签: c memory stack
9条回答
做个烂人
2楼-- · 2019-01-04 23:06

No, d[] will not be on the stack for the remainder of routine. But alloca() is different.

Edit: Kristopher Johnson (and simon and Daniel) are right, and my initial response was wrong. With gcc 4.3.4.on CYGWIN, the code:

void foo(int[]);
void bar(void);
void foobar(int); 

void foobar(int flag) {
    if (flag) {
        int big[100000000];
        foo(big);
    }
    bar();
}

gives:

_foobar:
    pushl   %ebp
    movl    %esp, %ebp
    movl    $400000008, %eax
    call    __alloca
    cmpl    $0, 8(%ebp)
    je      L2
    leal    -400000000(%ebp), %eax
    movl    %eax, (%esp)
    call    _foo
L2:
    call    _bar
    leave
    ret

Live and learn! And a quick test seems to show that AndreyT is also correct about multiple allocations.

Added much later: The above test shows the gcc documentation is not quite right. For years it has said (emphasis added):

"The space for a variable-length array is deallocated as soon as the array name's scope ends."

查看更多
走好不送
3楼-- · 2019-01-04 23:10

No, braces do not act as a stack frame. In C, braces only denote a naming scope, but nothing gets destroyed nor is anything popped off the stack when control passes out of it.

As a programmer writing code, you can often think of it as if it is a stack frame. The identifiers declared within the braces are only accessible within the braces, so from a programmer's point of view, it is like they are pushed onto the stack as they are declared and then popped when the scope is exited. However, compilers don't have to generate code that pushes/pops anything on entry/exit (and generally, they don't).

Also note that local variables may not use any stack space at all: they could be held in CPU registers or in some other auxiliary storage location, or be optimized away entirely.

So, the d array, in theory, could consume memory for the entire function. However, the compiler may optimize it away, or share its memory with other local variables whose usage lifetimes do not overlap.

查看更多
The star\"
4楼-- · 2019-01-04 23:11

There has already been given much information on the standard indicating that it is indeed implementation specific.

So, one experiment might be of interest. If we try the following code:

#include <stdio.h>
int main() {
    int* x;
    int* y;
    {
        int a;
        x = &a;
        printf("%p\n", (void*) x);
    }
    {
        int b;
        y = &b;
        printf("%p\n", (void*) y);
    }
}

Using gcc we obtain here two times the same address: Coliro

But if we try the following code:

#include <stdio.h>
int main() {
    int* x;
    int* y;
    {
        int a;
        x = &a;
    }
    {
        int b;
        y = &b;
    }
    printf("%p\n", (void*) x);
    printf("%p\n", (void*) y);
}

Using gcc we obtain here two different addresses: Coliro

So, you can't be really sure what is going on.

查看更多
登录 后发表回答