我想知道是否在堆栈上创建了一个变量。考虑以下三个具有变量b的函数f,g和h:
void f(int a) {
int b;
if (a == 0) {
return;
}
// do sth with b;
return;
}
void g(int a) {
if (a == 0) {
return;
}
int b;
// do sth with b;
return;
}
void h(int a) {
if (a == 0) {
return;
} else {
int b;
// do sth with b;
return;
}
}
答案 0 :(得分:5)
在哪种情况下会在堆栈上创建b?
由于b
是一个自动变量,因此通常都是这三个变量。在某些情况下,编译器可能会store b
in a CPU register,但是您不能强迫它发生,这是编译器的选择。
编译器优化级别如何影响此行为?
取决于编译器。
由于您假设您对b
做过(有用)的操作,因此可能无法对其进行优化。如果确实如此,则取决于编译器以及您对b
所做的实际工作,那么b
根本不会在堆栈中创建。
有没有一种更好的选择?
在需要使用变量的块的顶部,尽可能靠近变量b
的位置创建变量。
我会选择g()
,因为它是最简洁的功能(与其他字符相比,它使用最少的字符数来达到相同的目的)。而且,它会在使用前创建b
。
PS:当然g()
只能使用一个return
,但是您明白了。
答案 1 :(得分:1)
在哪种情况下会在堆栈上创建b?
编译器优化级别如何影响此行为?
在不考虑特定系统的情况下就不可能说出来。这取决于调用约定以及编译器如何优化代码。它可以分配在堆栈上或在寄存器内部。
话虽如此,您的3种情况大多与编码风格有关。如果需要b
并将其分配在堆栈上,则无论变量位于何处,都可能会尽早分配该内存。或类似地,如果编译器能够基于是否使用变量来优化内存使用,则无论变量声明在C源代码中位于何处,编译器都将在使用变量之前分配内存。
有没有一种更好的选择?
通常,使变量声明靠近使用它的位置。如果您可以缩小范围,那总是一件好事。但这是为了缩小范围,避免名称空间冲突,私有封装等。不是为了性能。
答案 2 :(得分:-2)
每个函数都有自己的框架(将存储所有局部变量,参数等的位置)。所有局部变量都是自动变量,因为它们将在return
运算符之后销毁。所有不带(malloc
,calloc
,realloc
等)创建的变量都将存储在堆栈中。因此,是的,代码中的所有变量都将存储在堆栈中。