这周一个同学问我一个C++问题,这个问题之前我也没有发现。问题如下:
#include <iostream>
using namespace std;

int& func()
......{
int i = 0;
reuturn i;
}

int main()
......{
int& a = func();
int b = func();

cout << a << " " << b << endl;

return 0;
}
在Visual C++ 6.0和Visual C++ 2005中的输出结果:
0 0
在g++中的输出结果:
0 0
同学问的时候我直接就说这个编译通不过,因为func函数返回一个局部变量的引用,便一起要报错的。但那个同学说在VC6.0下能通过,我也特别茫然,于是回来试着调了一下,发现在VC6.0下果然能输出结果。于是便开始思考这是为什么?
在VC6.0下用反汇编方式看了一下,发现了问题的答案:
6: int& func()
7: ...{
00401890 push ebp
00401891 mov ebp,esp
00401893 sub esp,44h
00401896 push ebx
00401897 push esi
00401898 push edi
00401899 lea edi,[ebp-44h]
0040189C mov ecx,11h
004018A1 mov eax,0CCCCCCCCh
004018A6 rep stos dword ptr [edi]
8: int i = 0;
004018A8 mov dword ptr [ebp-4],0
9: return i;
004018AF lea eax,[ebp-4]
10: }
004018B2 pop edi
004018B3 pop esi
004018B4 pop ebx
004018B5 mov esp,ebp
004018B7 pop ebp
004018B8 ret

12: int main(int argc, char* argv[])
13: ...{
004018D0 push ebp
004018D1 mov ebp,esp
004018D3 sub esp,48h
004018D6 push ebx
004018D7 push esi
004018D8 push edi
004018D9 lea edi,[ebp-48h]
004018DC mov ecx,12h
004018E1 mov eax,0CCCCCCCCh
004018E6 rep stos dword ptr [edi]
14: int& a = func();
004018E8 call @ILT+525(func) (00401212)
004018ED mov dword ptr [ebp-4],eax
15: int b = func();
004018F0 call @ILT+525(func) (00401212)
004018F5 mov eax,dword ptr [eax]
004018F7 mov dword ptr [ebp-8],eax
我们看第9行return i后有一行汇编代码lea eax,[ebp-4],这行代码正好将变量i的值返传给了eax,然后在第14行的mov dword ptr [ebp-4],eax,这行代码有讲eax的值传给了a,于是func函数中的局部变量i的值就被返回了。这是我自己的看法,希望大家来讨论,如果不对,请一定要告诉我。谢谢!


















0 0
在g++中的输出结果:
0 0
同学问的时候我直接就说这个编译通不过,因为func函数返回一个局部变量的引用,便一起要报错的。但那个同学说在VC6.0下能通过,我也特别茫然,于是回来试着调了一下,发现在VC6.0下果然能输出结果。于是便开始思考这是为什么?
在VC6.0下用反汇编方式看了一下,发现了问题的答案:










































