2010-01-08 104 views
2

编译器是否会为这两种语句生成相同的代码?c/C++通过参考堆栈帧布局的指针/参数传递参数

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

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

它只是写一个指针到foo的栈帧的参数部分吗?或者,在第二种情况下,调用者和foos的堆栈框架会以某种方式重叠,这样调用者的局部变量会将栈中的内存作为foo的参数?

+0

应该完全一样。每当怀疑这些情况时,最好检查一下拆卸情况。 – Andy 2010-01-08 13:46:55

回答

0

堆栈不能重叠。

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

并注意,即使堆栈中没有添加任何内容,决策也不能在编译函数时进行,而是在编译器正在处理调用函数时进行。一旦函数编译完成,它将不会根据调用的位置而改变。

+0

我认为提及链接器内联可能不适合这个问题。 – 2013-06-27 17:30:00

4

这两个呼叫应产生完全相同的代码,除非你有某种奇怪的编译器。

2

这取决于。

如果编译到一个库两者生成的代码将是等价的,如果在大多数平台上不相同的。

任何一个优秀的编译器将内联这样的小功能,所以它很可能是,而不是得到的东西的地址在栈上递增指向的值,它会而不是直接增加值。任何内联函数的堆栈帧都嵌入在调用者的堆栈帧中,所以在这种情况下会重叠。

+0

所以也需要一个指针的版本会被内联,而不是使用一个指针,直接在实际变量上工作? – Mat 2010-01-08 14:48:30

+0

@Mat:参考版本也可以内联。 – 2010-01-08 17:27:56

+0

@Mat:两者都可以内联直接在实际变量上工作。 – 2013-06-27 17:30:47

0

关于堆栈帧的重叠我发现下面的信息here

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

所以你的情况,如果仅在调用函数本地作用域的变量传递给foo2的重叠事情是可能的!