Re: How to pass STL containers (say a vector) ?
Marek Vondrak skrev:
I don't think that the compiler that comes with MS VisualStudio 2003
does RVO, even for simple cases.
It surely does. VC 6.0 also did if I do not remember wrong. Remember
that not all compiles will result in RVO.... you have to enable at
least some optimisations.
I dare not to agree (sorry for being offtopic). Maybe this all depends on
Happily this group is not moderated ;-)
the definition of what RVO is but the Microsoft compilers always behaved
like this (at least MSVC6, 7 and 7.1). Either the whole function is inlined
and the temporary is eventually eliminated (this is not a RVO) or a function
call is made and the temporary is not eliminated. This is demonstrated by
the following dumb test case:
-- test.cpp --
[snipped]
I must admit I had some trouble following your assembly listing (and
also your program - why writing the code inside a class and why
operator+??). In particular i failed to see where operator+ (which must
be the interesting function) did copy the result back and where the
local copy got destroyed. Instead, I made my own program ;-). :
#include <iostream>
struct test
{
test();
test(test const& rhs);
int i;
};
test::test() { std::cout << "test::test\n";}
test::test(test const& rhs) { std::cout << "test::test(test const&
rhs)\n";}
test func()
{
test t;
return t;
}
test func2(test const& tf)
{
test t(tf);
return t;
}
int main()
{
test t1(func());
test t2(func2(t1));
}
The program prints
"test::test
test::test(test const& rhs)"
which is exactly what you'd expect with RVO. Assembly for the two
test-functions:
PUBLIC ?func@@YA?AUtest@@XZ ; func
; Function compile flags: /Ogtpy
; COMDAT ?func@@YA?AUtest@@XZ
_TEXT SEGMENT
___$ReturnUdt$ = 8 ; size = 4
?func@@YA?AUtest@@XZ PROC ; func, COMDAT
; 15 : {
00000 56 push esi
; 16 : test t;
00001 8b 74 24 08 mov esi, DWORD PTR ___$ReturnUdt$[esp]
00005 8b ce mov ecx, esi
00007 e8 00 00 00 00 call ??0test@@QAE@XZ ; test::test
; 17 : return t;
0000c 8b c6 mov eax, esi
0000e 5e pop esi
; 18 : }
0000f c3 ret 0
?func@@YA?AUtest@@XZ ENDP ; func
_TEXT ENDS
PUBLIC ?func2@@YA?AUtest@@ABU1@@Z ; func2
; Function compile flags: /Ogtpy
; COMDAT ?func2@@YA?AUtest@@ABU1@@Z
_TEXT SEGMENT
___$ReturnUdt$ = 8 ; size = 4
_tf$ = 12 ; size = 4
?func2@@YA?AUtest@@ABU1@@Z PROC ; func2, COMDAT
; 23 : test t(tf);
00000 8b 44 24 08 mov eax, DWORD PTR _tf$[esp-4]
00004 56 push esi
00005 8b 74 24 08 mov esi, DWORD PTR ___$ReturnUdt$[esp]
00009 50 push eax
0000a 8b ce mov ecx, esi
0000c e8 00 00 00 00 call ??0test@@QAE@ABU0@@Z ; test::test
; 24 : return t;
00011 8b c6 mov eax, esi
00013 5e pop esi
; 25 : }
which verifies that RVO indeed is in effect. This is for Microsoft
Visual Studio 2005
Version 8.0.50727.42 (RTM.050727-4200) as I do not have the older
Visual C++ compilers at home, but you can copy/paste and easily verify
my code.
/Peter