变量声明是否意味着内存分配?

是否可以准确地说出来

void f() { int x; ... } 

int x; ”表示在堆栈上分配sizeof(int)字节?

那有什么规格吗?

标准中没有任何内容要求存在堆栈。 标准中没有任何内容要求局部变量需要为其分配内存。 变量可以放在寄存器中,甚至可以作为优化完全删除。

没有关于此的规范,您的假设通常(但不总是)是错误的。 考虑一些代码

 void f() { int x; for (x=0; x<1000; x++) { // do something with x } // x is no more used here } 

首先,优化编译器会将x放在机器的某个寄存器中,而不会消耗任何堆栈位置(除非您使用地址&x执行某些操作,例如将其存储在全局中)。

此外,编译器可以展开该循环 ,并从生成的代码中删除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的书中的连续编译 )。

顺便说一句,如果使用GCC,您可以使用例如MELT探针 (或使用gcc -fdump-tree-all来检查其中间(Gimple)表示,这会产生数百个转储文件!)。

来自GNU :

3.2.1 C程序中的内存分配

声明自动变量(例如函数参数或局部变量)时会发生自动分配。 输入包含声明的复合语句时会分配自动变量的空间,并在退出该复合语句时释放。 在GNU C中,自动存储的大小可以是变化的表达式。 在其他C实现中,它必须是常量。

这取决于很多因素。 编译器可以优化并从堆栈中删除它,将值保持在寄存器中。 等等

如果你在debug中编译它肯定会在堆栈中分配一些空间,但你永远不会知道。 这没有指定。 唯一指定的是变量的可见性以及变量的大小和算术。 有关更多信息,请参阅C99规范 。