在连续函数调用的情况下,C编译器是否优化了执行堆栈?

在连续函数调用的情况下,C编译器是否优化了执行堆栈?,c,embedded,compiler-optimization,callstack,C,Embedded,Compiler Optimization,Callstack,我有一个关于调用堆栈行为的基本问题。 我想知道当一个函数在另一个函数的末尾被调用时,系统如何管理调用堆栈内存 例如: void FunctionOne(void) { [...] // Various code operations FunctionTwo(); } void FunctionTwo(void) { [...] // Various code operation FunctionThree(); } void FunctionThree(v

我有一个关于调用堆栈行为的基本问题。 我想知道当一个函数在另一个函数的末尾被调用时,系统如何管理调用堆栈内存

例如:

void FunctionOne(void)
{
    [...] // Various code operations
    FunctionTwo();
}


void FunctionTwo(void)
{
    [...] // Various code operation
    FunctionThree();
}


void FunctionThree(void)
{
    [...] // Various code operation
    FunctionFour();
    [...] // Various code operation
}
当执行从FunctionOne()跳到FunctionTwo()时,调用堆栈内存是否被清除,因为调用FunctionTwo()后没有指令

当堆栈内存从FunctionTwo()转到FunctionTwo()时,它是否保持了整个执行级别

或者从一开始我就错了,关于调用堆栈的工作原理和用途


感谢您的帮助。

事实上,从
functionOne()
functionTwo()
和从
functionTwo()
functionTwo()
的调用可以在经过一些特定调整后以跳转的形式生成,以考虑调用方的参数和局部变量(可以进行堆栈清理)。这就是所谓的尾部调用优化。它们也可以内联生成,被调用函数的代码成为调用函数的一部分

C编译器是否执行尾部调用优化、内联生成或其他更高级的技巧是实现质量的问题。这样做可以提高代码速度,减少堆栈使用,但会使调试更加困难,因为调用堆栈可能会使跟踪变得混乱

该标准对此没有任何要求,编译器必须生成代码,就像调用正常进行一样。

应该与以下照片类似:

否,调用函数时不会“清理”调用堆栈,否则它不会是堆栈。我建议您阅读?然而,编译器很可能会“内联”一个或多个函数调用,在这种情况下,根本不会有任何返回地址等的堆叠。虽然这个答案是正确的,但具有相同信息但以书面形式的编译器更容易访问,因此对更多用户更有利。另外,解释一下为什么堆栈会以这种方式工作也会很有帮助。谢谢你的解释!有些编译器对函数支持
#pragma noreturn
,然后可以相应地格式化堆栈帧。@托夫罗:我相信
#pragma noreturn
告诉编译器函数永远不会返回,要么是因为它终止了程序,要么是因为它被设计成有一个无止境的循环。与当前问题没有关联。当然是。noreturn函数可以有一个优化的(更小的)堆栈帧,因为它们可以丢弃堆栈。@tofro:好的,但没有迹象表明OP问题中的任何函数都具有此属性。