Prev: Trying to come to terms with typecasting operators
Next: C++ Middleware Writer version 1.10 is now on line
From: George Neuner on 2 Dec 2009 05:01 On Wed, 2 Dec 2009 07:05:08 CST, "Martin B." <0xCDCDCDCD(a)gmx.at> wrote: >George Neuner wrote: >> On Sat, 28 Nov 2009 02:39:57 CST, "Martin B." <0xCDCDCDCD(a)gmx.at> >> wrote: >> >>> George Neuner wrote: >>> >>>> My best guess is that it's too much trouble - in general - for the >>>> compiler to decide whether the temporary return object can be renamed >>>> and used directly or will need to be destructed in the caller - so >>>> there is a blanket edict against inlining such functions. >>> Hmmm ... VC++ will always do RVO, i.e., there will never be a temporary >>> object for the string object, even if all optimizations are turned off. >>> So I can't imagine how the temporary could pose a problem here. >> >> The compiler always _tries_ to do RVO, but there are plenty of cases >> where it is not possible - one of which is passing an object by value >> where a reference is expected (a Microsoft extension). >> >> If you do something like: >> >> string G() { ... } >> string F( string &in ) { string out; ...; return out; } >> >> string x = F( G() ); >> >> you'll find that the return value from F() is optimized as expected >> but for F(G()) the return value from G() is a hidden stack temporary, >> a reference to which is then passed to F(). >> > >Cheers, that's an interesting point. >One might argue though that the hidden stack temporary "belongs" to the >F(.) call and thus does say nothing about RVO. :-) >That is, given: > > string G() { string s; ... returns s; } > string F(string &in) { string out; ... returns out; } > >and given two different code versions: > > void t3() { // uses MS extension > string s; > s = F( G() ); > } > > void t4() { > string s; > string tmp(G()); > s = F( tmp ); > } > >this will essentially generate the same assembly for t3 and t4 so I'm >really not sure if we can and should say that "RVO does not happen". I suppose you can make the case that the temporary somehow belongs to F(), but in any event you can show that it isn't optimized away with the following: class myString : public string { public: myString() { cout << '+'; } myString( char* src ) : string( src ) { cout << '+'; } myString( myString &src ) : string( src ) { cout << '='; } ~myString() { cout << '-'; } }; myString GetInput( char* prompt ) { char input[100]; cout << prompt; cin.getline( input, 99, '\n'); return myString(input); } myString Find(myString &input,myString &oldtext,myString& newtext) { size_t where; where = input.find( oldtext ); if ( where != string::npos ) { input.replace( where, oldtext.length(), newtext, 0, newtext.length() ); } return input; } int main( void ) { myString oldtext = GetInput("Find:"); myString newtext = GetInput("Replace With:"); myString text = Find( GetInput("In:"), oldtext, newtext ); cout << text << endl; return 0; } I'm requiring user input so the compiler doesn't optimize objects away by value propagation. When you run it, you'll see along with the prompts and your input "+++=----" ... 3 normal constructions, a copy construction and 4 destructions - proving that there is a hidden temporary object. You do need MS language extensions enabled to compile this. George -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Pages: 1 2 3 Prev: Trying to come to terms with typecasting operators Next: C++ Middleware Writer version 1.10 is now on line |