C ++函数调用与新建模块在堆栈上进行推送/弹出
我正在阅读有关C ++中的变量作用域,并遇到一个有趣的块结构:
int main(int argc, char **argv) {
int local;
{ // New level of scope
int more_local;
}
return 0;
}
我知道变量会在每个块的结尾处由弹出式大括号弹出堆栈}
。
我也读过函数调用也将它们的变量推入堆栈,并在通过关闭大括号}
表示的调用结束时终止:
void foo() {
int more_local;
}
int main(int argc, char **argv) {
int local;
foo();
return 0;
}
在这两种情况下堆栈的处理方式有何不同,两者的优缺点是什么?
那么,你可以说你的第一个例子可以被看作是内联函数。 :P
但通常,函数调用和打开一个新的scope
与彼此无关。
当你调用一个函数时,函数返回后,返回地址和所有参数都会被叠加并从中弹出。
当打开一个新的scope
,你可以简单地在该作用域的末尾调用该作用域内所有对象的析构函数; 这决不会保证这些变量占用的实际空间立即从堆栈中弹出。 它可以,但是空间也可以简单地被函数中的其他变量重用,这取决于编译器/优化器的奇思妙想。
通过函数调用,您将返回地址推入堆栈并创建新的堆栈帧。 如果您只是将部分代码放在大括号中,那么您正在定义一个新的范围,如您所说。 它们就像控制语句后面的任何代码块,如if,for,while等。
你不能在这里谈论优点和缺点,因为这是两个完全不同的东西。 没有太多的情况下,你会从花括号中的代码块中获益,并且它可以使代码难以阅读。
int more_local;
将在两种情况下被放置在堆栈上。 但第二种情况会有函数调用的开销。
我建议你考虑一下这个:
void foo()
{
int local;
{ // New level of scope
int more_local_1;
}
{ // New level of scope
int more_local_2;
}
}
这里more_local_1
和more_local_2
可能共享相同的内存位置。 一旦它用于more_local_1
并在第二个作用域中用于more_local_2
变量。
上一篇: C++ Function Call vs. New Blocks for Push/Popping on the Stack