705bb076   
   From: daniel.kruegler@googlemail.com   
      
   On 2012-01-16 00:15, Andrzej Krzemieński wrote:   
   > The current standard says (12.8, p. 31 and 32) that the copy/move from   
   > an automatic object into a temporary returned by a function as well as   
   > the copy/move from a temporary to an automatic object can be elided,   
   > thus avoiding any copying/moving in the following example.   
   >   
   > vecotr generate()   
   > {   
   > vecotr ans;   
   > populate(ans);   
   > return ans;   
   > }   
   >   
   > auto vec = generate();   
      
   In the following I assume "vecotr" is supposed to be "vector"   
   (This is not really necessary, but it helps reflecting upon assumed semantics   
   of your incomplete code).   
      
   > The standard also says that this optimization is even allowed if copy/   
   > move ctor or destructor have side effects. This somehow implies that   
   > it is only constructor's or destructor's side effects that can affect   
   > program's behaviour if elided.   
      
   I don't think that only a restrictive form of side-effect elimination is   
   implied by the current wording as you describe. The current wording describes   
   a specific *model* transformation and from this side-effects can be deduced.   
      
   > But how about the following case, if I   
   > slightly change function generate():   
   >   
   > vecotr generate()   
   > {   
   > vecotr ans;   
   > populate(ans);   
   > ScopeGuard g = [&]{ ans.clear(); }   
   > return ans;   
   > }   
   >   
   > ScopeGuard woks such that it registers a callback in the constructor,   
   > and calls the callback in the destructor. If copy elision is not   
   > performed, the additional call to function clear() has no impact on   
   > the program, because we are working on a local copy. However, if the   
   > copies are elided, the auto variable 'ans' inside the function, and a   
   > temporary, and the initialized global variable 'vec' are to be treated   
   > as the same object. In this case, if I interpret the standard   
   > correctly, the value of global 'vec' will be cleared. This would not   
   > have been the case if the moves were not elided. Thus, copy elision   
   > may change program behaviour even if constructors and destructors have   
   > no side effects.   
   >   
   > Now, to my questions.   
   > 1. Is my interpretation of the standard correct?   
      
   Yes. Note that p31 says:   
      
   "In such cases, the implementation treats the source and target of the omitted   
   copy/move operation as simply two different ways of referring to the same   
   object, and the destruction of that object occurs at the later of the times   
   when the two objects    
   would have been destroyed without the optimization."   
      
   This "treatment" description makes clear that during RVO there is only one   
   object where without RVO there are two objects. Your test case just makes it   
   observable whether the single object (RVO transformation model) or the first   
   object (non-RVO model) is    
   modified, which is fine.   
      
   > 2. Is this behaviour intended?   
      
   I don't know, but the wording looks pretty clear to me. In your example the   
   appropriate way to write portable code is to rewrite your modified code to the   
   form:   
      
   vector generate()   
   {   
    vector ans;   
    populate(ans);   
    {   
    ScopeGuard g = [&]{ ans.clear(); }   
    }   
    return ans;   
   }   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|