所有局部变量是否在 C 中函数执行开始时同时构造?

Mos*_*man 1 c

说我有一个这样的功能:

int myfunc()
{
    int a;
    // do something
    int b;
    // do something
}
Run Code Online (Sandbox Code Playgroud)

当我调用 myfunc() 时,b 的内存分配是否在 a 之后发生?或者是在第一个“做某事”完成后创建的。

Ant*_*ala 5

首先,该标准不使用术语构建。变量被定义初始化分配给,但没有被构造。定义要求编译器为变量保留内存

标准说具有自动存储持续时间的变量的生命周期从入口延伸到块,直到执行以任何方式结束。它们在执行相应的行时被初始化。在一个对象的生命周期内,它会为它保留内存,并且它会驻留在一个固定的地址上。

给定一个程序

#include <stdio.h>

int main(void) {
    int a = 0;

foo:;
    int b = 42;
    print("%d %d\n", a, b);
    a ++;
    b ++;
    goto foo;
}
Run Code Online (Sandbox Code Playgroud)

b将有一个恒定的地址的整个持续时间main的功能,也是如此a,不过b是重新初始化以后每隔goto


然而,该标准还表示,只要可执行文件的外部行为就像程序是根据标准文本翻译的一样,实现就不需要生成执行标准中设置的事情的可执行文件。这被称为 as -if 规则。例如,如果您没有观察到它们为它们保留了内存,或者您没有观察到它们的address,那么编译器不一定需要为它们保留内存。

例如,如果您有以下程序:

#include <stdio.h>

int main(void) {
    int a = 0;
    for ( ; a < 3; a++) {
        printf("*");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你问“什么时候为a”保留内存,然后知道 GCC 和 Clang 都会使用 -O3 将其编译为一个可执行文件,其机器代码与

#include <stdio.h>

int main(void) {
    putchar('*');
    putchar('*');
    putchar('*');
}
Run Code Online (Sandbox Code Playgroud)

现在,什么时候a“构建”了