在C中的堆栈上创建变量

时间:2018-11-08 09:12:10

标签: c function stack

我想知道是否在堆栈上创建了一个变量。考虑以下三个具有变量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;
    }
}
  1. 在哪种情况下会在堆栈上创建b?
  2. 编译器优化级别如何影响此行为?
  3. 有没有一种更可取的选择?

3 个答案:

答案 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运算符之后销毁。所有不带(malloccallocrealloc等)创建的变量都将存储在堆栈中。因此,是的,代码中的所有变量都将存储在堆栈中。