c/c++通过指针传递参数/通过引用堆栈帧布局传递参数
编译器会为这两个语句生成相同的代码吗?
foo1(int* val){(*val)++;}
foo2(int &val){val++;}
它会简单地将一个指针写入 foo 堆栈帧的参数部分吗?或者,在第二种情况下,调用者和 foos 的堆栈帧是否会以某种方式重叠,以便调用者的局部变量在堆栈上占用与 foo 的参数相同的内存?
Will the compiler produce the same code for both of these statements?
foo1(int* val){(*val)++;}
foo2(int &val){val++;}
Will it simply write a pointer into the parameter part of foo's stack frame? Or, in the second case, will the callers' and foos' stack frames somehow overlap such that the callers' local variable takes the same memory on the stack as the parameter for foo?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这两个调用应该生成完全相同的代码,除非您有某种奇怪的编译器。
Those two calls should generate exactly the same code, unless you have some kind of weird compiler.
这取决于。
如果编译到库中,在大多数平台上为两者生成的代码即使不相同,也将是等效的。
任何好的编译器都会内联这样一个小函数,因此很可能不是获取堆栈上某个内容的地址来递增指向的值,而是直接递增该值。任何内联函数的堆栈帧都嵌入到调用者的堆栈帧中,因此在这种情况下它们将重叠。
It depends.
The code generated for both will be equivalent if not identical on most platforms if compiled to a library.
Any good compiler will inline such a small function, so it is quite possible that rather than getting the address of something on the stack incrementing the pointed-to value, it will instead increment the value directly. Any inlined function's stack frame is embedded in the caller's stack frame, so the will overlap in that case.
堆栈不能重叠。
考虑到参数可以是全局对象、堆对象,或者即使存储在堆栈中,它也可能不是最后一个元素。根据调用约定,其他元素可能会放置在一个堆栈帧和传递给函数的参数(即返回地址)之间...
并且请注意,即使堆栈中没有添加任何内容,编译时也无法做出决定函数,而是当编译器处理调用函数时。一旦函数被编译,它就不会根据调用的位置而改变。
The stacks cannot be made to overlap.
Consider that the argument could be a global, a heap object, or even if stored in the stack it could be not the very last element. Depending on the calling convention, other elements might be placed in between one stack frame and the parameters passed into the function (i.e. return address)...
And note that even if nothing was added in the stack, the decision cannot be made while compiling the function, but rather when the compiler is processing the calling function. Once the function is compiled, it will not change depending on where it is called from.
关于堆栈帧的重叠,我在此处找到了以下信息
:
出于某些目的,子例程的堆栈帧与其调用者的堆栈帧可以被认为是重叠的,重叠部分由参数从调用者传递到被调用者的区域组成。在某些环境中,调用者将每个参数压入堆栈,从而扩展其堆栈框架,然后调用被调用者。在其他环境中,调用者在其堆栈帧顶部有一个预先分配的区域,用于保存它提供给它调用的其他子例程的参数。该区域有时称为传出参数区域或标注区域。在这种方法下,该区域的大小由编译器计算为任何被调用的子例程所需的最大大小。
因此,在您的情况下,如果仅将调用者函数的本地范围中的变量传递给 foo2 重叠的事情可能是可能的!
regarding overlapping of stack frames I found the following info here
:
For some purposes, the stack frame of a subroutine and that of its caller can be considered to overlap, the overlap consisting of the area where the parameters are passed from the caller to the callee. In some environments, the caller pushes each argument onto the stack, thus extending its stack frame, then invokes the callee. In other environments, the caller has a preallocated area at the top of its stack frame to hold the arguments it supplies to other subroutines it calls. This area is sometimes termed the outgoing arguments area or callout area. Under this approach, the size of the area is calculated by the compiler to be the largest needed by any called subroutine.
So in your case if only variables in local scopes of caller functions are passed to foo2 overlapping thing may be possible!