我想知道编译器是否可以做到这些场景?
首先我们将 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();
调用者有责任将该共享部分的内容复制到该指针指示的位置。
如果将引用(或指针)传递给调用函数(调用者)中的局部变量,那么它将位于调用者堆栈帧上。请注意,我不知道任何架构,如果你掀起地毯并看看它在漂亮的表面下实际上是如何工作的,引用实际上并不是指针。该标准并不要求这样做,但至少在大多数架构中它是如何实现的 - 我实际上有兴趣了解如何实现它 - 但我没有花太多时间考虑它。
具有
struct
或 class
返回类型的函数的典型行为是它传递一个指向临时空间的“额外”参数来存储返回类型,例如:
T myfunc(int x, int y)
...
void foo()
{
...
T x = myfunc(2, 18);
...
}
将显示为相同(隐藏参数不一定是第一个参数 - 但它几乎肯定是第一个或最后一个):
void myfunc(T& hidden, int x, int y)
void foo()
{
...
T x;
myfunc(x, 2, 18);
...
}
实际上,堆栈帧并不是共享的,就像“我们传递位于或更早的调用者的堆栈帧中的指针一样”。
所以,是的,当然可以从当前被调用者访问早期调用者堆栈帧。