c / c ++通过引用堆栈框架布局通过指针/参数传递参数

时间:2010-01-08 13:23:39

标签: c++ reference pointers stackframe

编译器是否会为这两个语句生成相同的代码?

foo1(int* val){(*val)++;}

foo2(int &val){val++;}

它会简单地将指针写入foo堆栈帧的参数部分吗?或者,在第二种情况下,调用者和foos'堆栈帧是否会以某种方式重叠,以致调用者的局部变量在堆栈中获取与foo参数相同的内存?

4 个答案:

答案 0 :(得分:4)

这两个调用应该生成完全相同的代码,除非你有某种奇怪的编译器。

答案 1 :(得分:2)

取决于。

如果编译到库中,为两者生成的代码在大多数平台上都是等效的。

任何好的编译器都会内联这么小的函数,所以很可能不是让堆栈上某些东西的地址递增指向的值,而是直接递增值。任何内联函数的堆栈帧都嵌入在调用者的堆栈帧中,因此在这种情况下将重叠。

答案 2 :(得分:0)

不能使堆叠重叠。

考虑参数可以是全局的,堆对象,或者即使存储在堆栈中,它也可能不是最后一个元素。根据调用约定,其他元素可能放在一个堆栈帧和传递给函数的参数之间(即返回地址)......

请注意,即使堆栈中没有添加任何内容,也无法在编译函数时做出决定,而是在编译器处理调用函数时。编译函数后,它将不会根据调用函数的位置而改变。

答案 3 :(得分:0)

关于堆栈帧的重叠,我发现了以下信息here   :

出于某些目的,子例程的堆栈帧和其调用者的堆栈帧可以被认为是重叠的,重叠由参数从调用者传递给被调用者的区域组成。在某些环境中,调用者将每个参数压入堆栈,从而扩展其堆栈帧,然后调用被调用者。在其他环境中,调用者在其堆栈帧的顶部有一个预分配区域,用于保存它提供给其调用的其他子例程的参数。该区域有时被称为出局参数区域或标注区域。在这种方法下,编译器计算的区域大小是任何被调用子例程所需的最大值。

所以在你的情况下,如果只将调用函数的局部作用域中的变量传递给foo2,那么重叠的东西是可能的!