C/C++: 函数调用, 栈的大小是怎么被确定的

C/C++: 函数调用, 栈的大小是如何被确定的?
每个函数调用都要压栈, 
栈用来存放局部变量和形参以及状态指针,
可是很多时候变量是按程序逻辑动态创建的, 编译器不可能知道函数块需要多少局部变量啊?

比如这样一个函数: 
void test()
{
  if(someCondition) {double a = 123.0;} else {int b = 456;} // 栈的大小应按sizeof(a) 还是 sizeof(b)计算? 
}

或者, 是我理解有误, 栈的大小可以伸缩?



------解决方案--------------------
sizeof(a) + sizeof(b)
------解决方案--------------------
void test()
{
if(someCondition) {double a = 123.0;} else {int b = 456;} // 栈的大小应按sizeof(a) 还是 sizeof(b)计算?
}

----------------------
你要明确, 函数的所有局部变量都是进入函数的时候分配的. 并不是你定义的时候才分配!
所以, 无论 someCondition 是否成立, double a 和 int b 变量都会被分配. 而不是根据这个条件, 满足的时候分配 a, 不满足的时候分配 b.
------解决方案--------------------
探讨也就是说, 还是要为所有变量预留空间,不管它会不会在运行时被创建? 怎样用代码去窥探/证实这一点呢?

------解决方案--------------------
没错函数调用的确是是个压栈的过程; 函数返回后,压栈的数据被弹出。
栈的大小,应该由编译器和os共同决定吧。
编译器中,有frame 和 record的概念。来控制函数调用和返回。以及发生异常时,栈的回退(unwinded)等。

函数调用中其相关信息和其局部变量的空间都在栈上分配,而且是编译器自动分配。

至于你说的是sizeof(a) 还是sizeof(b);个人觉得应该大于sizeof(a) + sizeof(b);

因为函数调用的过程,是一个上下文切换的过程,其间,首先要保存现场、然后将函数的返回地址及局部变量压栈、执行函数、返回、恢复现场。 如果写过汇编程序,这个就很容易理解了。
这些都是有编译器实现的,具体细节我们不必关心。

alloc 可以在栈上分配内存。你可以通过在函数内部定义一个足够大数组,来看看,你的编译器分配的stack size。

------解决方案--------------------
...
简单点 花点时间了解下ebp,esp寄存器的用途,用Ollydbg随便打开一个程序,单步跟踪下函数调用的过程,观察栈的变化 就明白了
------解决方案--------------------
这个兄弟解释的差不多。stack 和 stack frame弄清楚了就明白了。
建议学习一下linux内核。
探讨

引用:有线程栈,我自己理解的“函数栈”是线程栈的子站
线程栈是编译阶段定死的,windows默认貌似4MB,这个在编译选项中可调的
“函数栈”又分两个部分,第一是参数,第二是函数的局部变量。
参数是需要随着函数调用入栈出栈的,一个函数的局部变量也可以看成是一个元素,函数调用的时候入栈

在一个内部来说,每个句柄变量也是在栈上,位置在编译阶段就定好了

没有所谓的……