home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,525 of 33,346   
   Martin B. to Howard Hinnant   
   Re: Will a const object be moved on retu   
   03 Oct 11 11:45:27   
   
   3545ca2e   
   From: 0xCDCDCDCD@gmx.at   
      
   On 02.10.2011 00:36, Howard Hinnant wrote:   
   > On Sep 30, 9:25 pm, Dave Abrahams  wrote:   
   >> on Fri Sep 30 2011, Howard Hinnant  wrote:   
   >>> struct A   
   >>> {   
   >>>      A(A&);   
   >>>      A(const A&);   
   >>>      A(A&&);   
   >>>      A(const A&&);   
   >>>      // ...   
   >>> };   
   >>   
   >> I suppose.  What would the point be?   
   >>   
   >> But yeah, this is where the optimization "might break code."   
   >> Personally, if it's just in this (useless?) corner, I wouldn't mind.   
   >> (...)   
   >> I think the only way to fix it is to say "Surprise, surprise, surprise!"   
   >   
   > I'm not against voting for a breaking change.  But there's got to be   
   > sufficient benefit.  I'm not seeing sufficient benefit yet.   
   >   
   > Here are the exact words from the standard that we have today:   
   >   
   >> When the criteria for elision of a copy operation are met or   
   >> would be met save for the fact that the source object is a   
   >> function parameter, (...)   
   >   
   > These words set up completely backwards compatible behavior with C+   
   > +03.  "Ignoring const" breaks not only C++11, but C++03 as well.   
   > Here's the test to play with:   
   >   
   > //                        with rvo     w/o rvo   
   > // C++03                    ok          ok     A(A&  a)  A(const A&  a)   
   > // C++11 w/o rvalue-ref     ok          ok     A(A&  a)  A(const A&  a)   
   > // C++11 with rvalue-ref    ok          ok     A(A&&  a) A(const A&&  a)   
   >   
   > (:::)   
   > public:   
   >     int data_;   
   >     enum {unknown, is_const, is_non_const};   
   >   
   >     explicit A(int data) : data_(data) {}   
   >   
   >     A(const A&  a)   
   >         : data_(a.data_)   
   >     {   
   >         std::cout<<  "A(const A&  a)\n";   
   >         assert(data_ == is_const);   
   >     }   
   >   
   >     A(A&  a)   
   >         : data_(a.data_)   
   >     {   
   >         std::cout<<  "A(A&  a)\n";   
   >         assert(data_ == is_non_const);   
   >     }   
   >   
   > #if HAS_RVALUE_REF   
   >     A(const A&&  a)   
   >         : data_(a.data_)   
   >     {   
   >         std::cout<<  "A(const A&&  a)\n";   
   >         assert(data_ == is_const);   
   >     }   
   >   
   >     A(A&&  a)   
   >         : data_(a.data_)   
   >     {   
   >         std::cout<<  "A(A&&  a)\n";   
   >         a.data_ = unknown;   
   >         assert(data_ == is_non_const);   
   >     }   
   > #endif   
   > };   
   >   
   > A   
   > f1(bool b)   
   > {   
   >     A a(A::is_non_const);   
   > #if RVO == 0   
   >     if (b)   
   >         return A(A::is_non_const);   
   > #endif   
   >     return a;   
   > }   
   >   
   > A   
   > f2(bool b)   
   > {   
   >     typedef const A CA;   
   >     CA a(A::is_const);   
   > #if RVO == 0   
   >     if (b)   
   >         return CA(A::is_const);   
   > #endif   
   >     return a;   
   > }   
   >   
   > int main()   
   > {   
   >     A a1 = f1(false);   
   >     assert(a1.data_ == A::is_non_const);   
   >     A a2 = f2(false);   
   >     assert(a2.data_ == A::is_const);   
   > }   
   >   
   > I've run this test 6 ways:   
   >   
   > *  In C++03 mode with and without RVO enabled.   
   > *  In C++11 mode, but without the move constructors, with and without   
   > RVO enabled.   
   > *  In C++11 mode, with the move constructors, with and without RVO   
   > enabled.   
   >   
   > It all currently **just works**.  This is by careful design by the CWG   
   > (I can't take credit for it).  I'll need a very large carrot to   
   > dismiss these carefully crafted rules.  Or perhaps new rules that   
   > somehow don't dismiss the current behavior.   
   >   
      
   I have to say I don't find this example compelling.   
   You are tightly coupling the value of an object to whether it's const.   
   How much sense does that make??   
      
   *And* in your example, in main() you have a *non const* `A` object that   
   has its member set to `is_const`. While you do not assert on this, this   
   doesn't make any sense to me.   
      
   (Plus, how much sense do multiple const/non-const copy/move ctors make   
   anyway??)   
      
   Not to say that -- after careful consideration -- "we" could come to the   
   conclusion that this "ignore const" optimization cannot be implemented   
   without breaking (too much) code. Unfortunately, I do not know enough   
   about the fine print regarding const and move to really tell.   
      
   cheers,   
   Martin   
      
      
   --   
         [ 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)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca