在
中说出来是否准确void f() {
int x;
...
}
“int x;
”表示在堆栈上分配sizeof(int)
个字节?
是否有任何规格?
答案 0 :(得分:21)
标准中没有任何内容要求存在堆栈。标准中没有任何内容要求局部变量需要为其分配内存。变量可以放在寄存器中,甚至可以作为优化完全删除。
答案 1 :(得分:7)
没有关于此的说明,您的假设通常(但不总是)是假的。 考虑一些代码,如
void f() {
int x;
for (x=0; x<1000; x++)
{ // do something with x
}
// x is no more used here
}
首先,优化编译器会将x
放在机器的某个寄存器中,而不会占用任何堆栈位置(除非您使用地址&x
执行某些操作,例如将其存储在全局中)。 / p>
编译器也可以unroll that loop,并从生成的代码中删除x
。例如,许多编译器将替换
for (x=0; x<5; x++) g(x);
相当于
g(0); g(1); g(2); g(3); g(4);
也许替换
for (x=0; x<10000; x++) t[x]=x;
类似
for (α = 0; α < 10000; α += 4)
{ t[α] = α; t[α+1] = α+1; t[α+2] = α+2; t[α+3] = α+3; };
其中α是一个新变量(或者可能是x
本身)。
此外,可能没有堆叠。对于C来说,它并不常见,但是其他一些语言没有任何堆栈(参见例如旧A.Appel的书使用continuation编译)。
顺便说一句,如果使用GCC,您可以检查其中间(Gimple)表示,例如MELT probe(或使用产生数百个转储文件的gcc -fdump-tree-all
!)。
答案 2 :(得分:3)
来自GNU:
3.2.1 C程序中的内存分配
声明自动变量时会发生自动分配 例如函数参数或局部变量。空间 当复合语句包含时,自动变量被分配 输入声明,并在复合声明时释放 退出了。在GNU C中,自动存储的大小可以是 表达方式各不相同在其他C实现中,它必须是a 恒定。
答案 3 :(得分:1)
这取决于很多因素。编译器可以优化并从堆栈中删除它,将值保持在寄存器中。等。
如果你在debug中编译它肯定会在堆栈中分配一些空间,但你永远不会知道。这没有指定。唯一指定的是变量的可见性以及变量的大小和算术。有关详细信息,请查看C99 spec。
答案 4 :(得分:0)
我认为这取决于编译器。我为Code :: Blocks和Dev-C ++使用了默认的编译器,看起来初始化期间分配了内存。在下面的cout语句中,将n2更改为n1将给出相同的答案。但是,如果我将n1初始化为某个值,或者如果在显示平均值之前显示n2,则会得到不同的答案,这是垃圾。 请注意,由于变量未初始化,因此VS可以通过给出错误来正确处理此问题。
void getNums();
void getAverage();
int main()
{
getNums();
getAverage();
return 0;
}
void getNums()
{
int num1 = 4;
double total = 10;
}
void getAverage()
{
int counter;
double n1 , n2;
cout << n2/counter << endl;
}