总所周知,函数体返回值那里没有&,就会返回一个中间变量。
class sale {
public:
int i = 1;
};
sale add(const sale& lift, const sale& right) {
sale sum = lift;
sum.i += right.i;
return sum;
}
int main()
{
sale one;
sale two;
const sale& global = add(one, two);
}
假设有如上代码,进行反汇编后,汇编如下:
const sale& global = add(one, two);
00D51A32 8D 45 E8 lea eax,[two]
00D51A35 50 push eax
00D51A36 8D 4D F4 lea ecx,[one]
00D51A39 51 push ecx
00D51A3A E8 40 F9 FF FF call add (0D5137Fh)
00D51A3F 83 C4 08 add esp,8 #调用完毕后,清除栈空间
00D51A42 89 85 04 FF FF FF mov dword ptr [ebp-0FCh],eax #为中间变量分配空间
00D51A48 8B 95 04 FF FF FF mov edx,dword ptr [ebp-0FCh]
00D51A4E 89 55 D0 mov dword ptr [ebp-30h],edx #把中间变量复制给新的变量
00D51A51 8D 45 D0 lea eax,[ebp-30h] #导入新变量的地址
00D51A54 89 45 DC mov dword ptr [global],eax #把这个地址给 global,因为引用本质是指针
上面写的注释不一定对,但为什么这里要分配两次空间呢? 如果我换一个简单的程序:
int re() {
return 5;
}
int main()
{
//int a = 1;
const int& b = re();
}
他的汇编就和我想象中一样了,只分配一次空间:
const int& b = re();
00B019B2 E8 0E FA FF FF call re (0B013C5h)
00B019B7 89 45 E8 mov dword ptr [ebp-18h],eax #分配空间
00B019BA 8D 45 E8 lea eax,[ebp-18h] #把地址导入 eax
00B019BD 89 45 F4 mov dword ptr [b],eax #把 eax 赋值给 b,因为 b 是引用,相当于指针
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.