会不会共享呼叫者/被呼叫者堆栈帧的部分?

时间:2013-06-27 08:34:45

标签: c++ function memory-management compiler-construction stackframe

我想知道编译器是否可以使用这些场景?

首先我们将SomeDataType定义为:

struct SomeDataType{
public:
int a;
int b;
int c;
};

场景#1 __使用具有以下参考参数的被调用函数:

void doSomething(SomeDataType & input){
...
}

假设函数不是内联的,并且只有调用函数作用域的变量在程序中传递给该函数,并且关于引用不一定是指针的事实,放置输入参数的内存部分是共享的任何调用函数的堆栈帧和“doSomething”被调用函数的堆栈帧之间,以便“doSomething”可以解决该参数只是它在本地范围内寻址任何局部变量的方式,即通过向确定起始地址的基指针添加偏移量它的堆栈框架。

情景#2 _这对我来说似乎更不可能,但无论如何;关于返回类型为“SomeDataType”的结构的被调用函数:

SomeDataType doSomething(){
SomeDataType someStruct;
...
return someStruct;
};

结构“someStruct”所在的内存部分在任何调用者的堆栈帧和“doSomething”被调用函数的堆栈帧之间共享,因此在调用函数中考虑以下语句:

SomeDataType TheStruct=doSomething();

在使用“TheStruct”的调用者的范围内导致使用内存的相同部分,其中被调用者范围内的“SomeStruct”意味着基本上被调用函数不会在任何地方复制“someStruct”,即使需要复制也是如此比如在调用函数中有如下所示的语句,表明目标不是调用者范围内的结构:

*pntrToSomewhere=doSomething();

将该共享部分的内容复制到该指针所指示的位置是调用者的责任。

1 个答案:

答案 0 :(得分:0)

如果将引用(或指针)传递给调用函数(调用者)中的局部变量,那么它将位于调用者堆栈帧上。请注意,我不知道任何架构,如果你抬起地毯并看看它是如何在漂亮的表面下工作的,那么引用实际上并不是指针。标准并不要求它,但它至少是为大多数架构实现的 - 我实际上有兴趣理解你可以实现它的方式 - 但我没有花太多时间思考它。

具有structclass返回类型的函数的典型行为是它传递一个指向临时空间的“额外”参数来存储返回类型,例如:

 T myfunc(int x, int y)

 ...

 void foo()
 {
    ...
    T x = myfunc(2, 18);
    ...
 }

将显示为相同(隐藏的参数不一定是FIRST参数 - 但它几乎肯定是第一个或最后一个):

 void myfunc(T& hidden, int x, int y)

 void foo()
 {
    ...
    T x;
    myfunc(x, 2, 18);
    ...
 }

并不是真正的堆栈帧是共享的,就像“我们传递的指针位于之前或之前的调用者的堆栈帧中一样。

所以,是的,肯定会有当前被调用者访问早期调用者堆栈帧的访问权限。