C++函数调用中的栈分配相关技术问题咨询
C++函数参数传递相关问题解答
当调用函数时,若参数不是数组且未通过取地址符(&)显式指定按引用传递,则会按值传递。例如:
void boo (int a, int b) {} int main() { int var1 {1}; int var2 {2}; boo(var1,var2); return 0; }
在此场景中,整型变量var1和var2的值会被复制到函数boo()的参数a和b中,并存储在为boo()分配的栈帧内。
问题1
编写如下代码:
void boo (int a, int b) {} int main() { boo(1,2); return 0; }
整型字面量1和2属于右值,它们是否不会被存储在main()的栈帧中?
解答
不一定,具体取决于编译器的优化策略和目标平台的调用约定:
- 在未优化的编译模式下,编译器可能会把字面量1、2临时存入
main()的栈帧,再将值复制到boo()参数a、b所在的栈帧位置。 - 开启优化(如
-O2)时,编译器通常会直接通过寄存器传递字面量的值给boo(),不会在main()栈帧中存储这些字面量;即使需要通过栈传递,也可能直接在boo()的栈帧位置写入字面量值,跳过main()栈帧的存储步骤。
C++标准并没有强制要求右值必须存储在调用者栈帧中,具体行为由编译器实现决定。
问题2
改为编写如下代码:
void boo (int &a, int &b) {} int main() { int var1{1}; int var2{2}; boo(var1,var2); return 0; }
参数a和b是否仍会以某种备份形式存储在boo()的栈帧中?还是仅作为实际参数var1和var2的引用?
解答
从C++语义层面看,引用是变量的别名,a就是var1的别名,b就是var2的别名,不存在“备份”,对a的操作直接作用于var1,对b的操作直接作用于var2。
从底层实现角度,大部分编译器会通过指针来实现引用:此时boo()的栈帧中会存储var1和var2的内存地址(即指针),以此来关联引用与原变量。但这属于编译器的具体实现细节,C++标准并未规定引用必须用指针实现——如果编译器能直接追踪到引用对应的变量,也可以完全省略指针存储,直接操作原变量的内存。
无论底层如何实现,从语言语义上来说,引用不会产生原变量的备份。
内容的提问来源于stack exchange,提问作者ConventionalProgrammer
相关产品推荐
相关产品推荐

