编译器是否会为这两个语句生成相同的代码?
foo1(int* val){(*val)++;}
foo2(int &val){val++;}
它会简单地将指针写入foo堆栈帧的参数部分吗?或者,在第二种情况下,调用者和foos'堆栈帧是否会以某种方式重叠,以致调用者的局部变量在堆栈中获取与foo参数相同的内存?
答案 0 :(得分:4)
这两个调用应该生成完全相同的代码,除非你有某种奇怪的编译器。
答案 1 :(得分:2)
取决于。
如果编译到库中,为两者生成的代码在大多数平台上都是等效的。
任何好的编译器都会内联这么小的函数,所以很可能不是让堆栈上某些东西的地址递增指向的值,而是直接递增值。任何内联函数的堆栈帧都嵌入在调用者的堆栈帧中,因此在这种情况下将重叠。
答案 2 :(得分:0)
不能使堆叠重叠。
考虑参数可以是全局的,堆对象,或者即使存储在堆栈中,它也可能不是最后一个元素。根据调用约定,其他元素可能放在一个堆栈帧和传递给函数的参数之间(即返回地址)......
请注意,即使堆栈中没有添加任何内容,也无法在编译函数时做出决定,而是在编译器处理调用函数时。编译函数后,它将不会根据调用函数的位置而改变。
答案 3 :(得分:0)
关于堆栈帧的重叠,我发现了以下信息here :
出于某些目的,子例程的堆栈帧和其调用者的堆栈帧可以被认为是重叠的,重叠由参数从调用者传递给被调用者的区域组成。在某些环境中,调用者将每个参数压入堆栈,从而扩展其堆栈帧,然后调用被调用者。在其他环境中,调用者在其堆栈帧的顶部有一个预分配区域,用于保存它提供给其调用的其他子例程的参数。该区域有时被称为出局参数区域或标注区域。在这种方法下,编译器计算的区域大小是任何被调用子例程所需的最大值。
所以在你的情况下,如果只将调用函数的局部作用域中的变量传递给foo2,那么重叠的东西是可能的!