문제

전화하고 싶다면 Bar() 대신에 Foo(), 하다 Bar() foo ()가 반환하는 것에 대한 사본 (추가 오버 헤드)을 반환하거나 동일한 개체를 반환합니다. Foo() 임시 스택에 장소?

vector<int> Foo(){  
    vector<int> result;  
    result.push_back(1);  
    return result;  
}  
vector<int> Bar(){  
    return Foo();  
}
도움이 되었습니까?

해결책

둘 다 일어날 수 있습니다. 그러나 대부분의 컴파일러는 최적화하자마자 복사하지 않습니다.

코드에 사본이 있어야합니다. 그러나 컴파일러는 시맨틱과 프로그램을 변경하지 않는 사본을 제거 할 수 있습니다.

참고 : 이것이 사본이 실제로 완료 될지 여부를 확신 할 수 없으므로 올바르게 복사하는 것 외에는 아무것도 수행하는 사본 생성자가 없어야하는 이유입니다.

다른 팁

이것은 NRVO의 사소한 사례입니다 - 이름 리턴 값 최적화 (이름이 없기 때문에이 경우 오해). 스탠 립만 모자 a 블로그 항목 관련된 메커니즘에 대한 좋은 설명으로.

일반적으로 반환 된 사본을 반환합니다 vector<int>. 그러나 이것은 컴파일러가 수행 한 최적화에 크게 달려 있습니다. 다음 토론을 참조하십시오.

디버그 빌드

vector<int> Foo(){  
004118D0  push        ebp  
004118D1  mov         ebp,esp 
004118D3  push        0FFFFFFFFh 
004118D5  push        offset __ehhandler$?Foo@@YA?AV?$vector@HV?$allocator@H@std@@@std@@XZ (419207h) 
004118DA  mov         eax,dword ptr fs:[00000000h] 
004118E0  push        eax  
004118E1  sub         esp,0F4h 
004118E7  push        ebx  
004118E8  push        esi  
004118E9  push        edi  
004118EA  lea         edi,[ebp-100h] 
004118F0  mov         ecx,3Dh 
004118F5  mov         eax,0CCCCCCCCh 
004118FA  rep stos    dword ptr es:[edi] 
004118FC  mov         eax,dword ptr [___security_cookie (41E098h)] 
00411901  xor         eax,ebp 
00411903  push        eax  
00411904  lea         eax,[ebp-0Ch] 
00411907  mov         dword ptr fs:[00000000h],eax 
0041190D  mov         dword ptr [ebp-0F0h],0 
    vector<int> result;  
00411917  lea         ecx,[ebp-24h] 
0041191A  call        std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (411050h) 
0041191F  mov         dword ptr [ebp-4],1 
    result.push_back(1);  
00411926  mov         dword ptr [ebp-0FCh],1 
00411930  lea         eax,[ebp-0FCh] 
00411936  push        eax  
00411937  lea         ecx,[ebp-24h] 
0041193A  call        std::vector<int,std::allocator<int> >::push_back (41144Ch) 
    return result;  
0041193F  lea         eax,[ebp-24h] 
00411942  push        eax  
00411943  mov         ecx,dword ptr [ebp+8] 
00411946  call        std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (41104Bh) 
0041194B  mov         ecx,dword ptr [ebp-0F0h] 
00411951  or          ecx,1 
00411954  mov         dword ptr [ebp-0F0h],ecx 
0041195A  mov         byte ptr [ebp-4],0 
0041195E  lea         ecx,[ebp-24h] 
00411961  call        std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> > (411415h) 
00411966  mov         eax,dword ptr [ebp+8] 
}  

여기서 우리는 그것을 볼 수 있습니다 vector<int> result; 스택에 새 객체가 생성됩니다 [ebp-24h]

00411917  lea         ecx,[ebp-24h] 
0041191A  call        std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (411050h)

우리가 가면 return result; 발신자가 할당 한 스토리지에서 새 사본이 생성됩니다. [ebp+8]

00411943  mov         ecx,dword ptr [ebp+8] 
00411946  call        std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (41104Bh) 

그리고 소멸자는 로컬 매개 변수를 요구합니다 vector<int> result ~에 [ebp-24h]

0041195E  lea         ecx,[ebp-24h] 
00411961  call        std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> > (411415h) 

릴리스 빌드

vector<int> Foo(){  
00401110  push        0FFFFFFFFh 
00401112  push        offset __ehhandler$?Foo@@YA?AV?$vector@HV?$allocator@H@std@@@std@@XZ (401F89h) 
00401117  mov         eax,dword ptr fs:[00000000h] 
0040111D  push        eax  
0040111E  sub         esp,14h 
00401121  push        esi  
00401122  mov         eax,dword ptr [___security_cookie (403018h)] 
00401127  xor         eax,esp 
00401129  push        eax  
0040112A  lea         eax,[esp+1Ch] 
0040112E  mov         dword ptr fs:[00000000h],eax 
00401134  mov         esi,dword ptr [esp+2Ch] 
00401138  xor         eax,eax 
0040113A  mov         dword ptr [esp+8],eax 
    vector<int> result;  
0040113E  mov         dword ptr [esi+4],eax 
00401141  mov         dword ptr [esi+8],eax 
00401144  mov         dword ptr [esi+0Ch],eax 
    result.push_back(1);  
    return result;  
00401147  push        eax  
00401148  mov         dword ptr [esp+28h],eax 
0040114C  mov         ecx,1 
00401151  push        esi  
00401152  lea         eax,[esp+14h] 
00401156  mov         dword ptr [esp+10h],ecx 
0040115A  mov         dword ptr [esp+14h],ecx 
0040115E  push        eax  
0040115F  lea         ecx,[esp+1Ch] 
00401163  push        ecx  
00401164  mov         eax,esi 
00401166  call        std::vector<int,std::allocator<int> >::insert (401200h) 
0040116B  mov         eax,esi 
}  
0040116D  mov         ecx,dword ptr [esp+1Ch] 
00401171  mov         dword ptr fs:[0],ecx 
00401178  pop         ecx  
00401179  pop         esi  
0040117A  add         esp,20h 
0040117D  ret

라인 vector<int> result 벡터 할당자가 호출 사이트에서 수행되므로 벡터 할당을 호출하지 않습니다. Bar. 최적화는 FOO의 결과 사본을 만들지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top