[cfe-commits] r60900 - in /cfe/trunk: include/clang/Parse/Ownership.h

Howard Hinnant hhinnant at apple.com
Fri Dec 12 17:20:38 PST 2008


On Dec 12, 2008, at 6:24 PM, Howard Hinnant wrote:

>  here's a long shot:
>
>     ASTOwningResult& operator =(volatile ASTOwningResult&); // DO NOT
> IMPLEMENT
>
> However I suspect if they don't respect bind an rvalue to A&, they
> aren't going to respect not binding to a volatile either.

Oh, here's another solution:

#if VC_2005  // or however we spell it
   public:
#endif
     ASTOwningResult& operator =(ASTOwningResult& x)
#if !VC_2005
        ; // DO NOT IMPLEMENT
#else
      {
         return *this = moving::ASTResultMover<Destroyer>(x);
      }
   private:
#endif

Explanation (mainly for those not familiar with move semantics -- not  
preaching to Sebastian!):

Code such as:

     DefaultExpr = ParseCXXIdExpression();

will now compile on VC++ (/Za off or on), and on all other compilers.   
The downside is that only on VC++ (/Za off) the following code will  
compile and shouldn't:

     DefaultExpr = AnotherDefaultExpr;

This is the dreaded "moving from an lvalue with copy syntax".  If it  
looks like a copy, it should copy, and not move.  With:

     DefaultExpr = ParseCXXIdExpression();

one can not tell that it isn't a copy because you can't access the rhs  
of the assignment afterwards to check its value (so it is safe to move  
with copy syntax from rvalues (anonymous objects)).

But, on VC++ (/Za off) the dangerous move assignment will compile.   
However as soon as the code is compiled on a modern compiler, the  
mistake will be caught, and it is easy to fix:

     DefaultExpr = move(AnotherDefaultExpr);  // safe now, move  
assignment is explicit

Upon fixing one should double check that the value of  
AnotherDefaultExpr is not accessed after this move assignment, though  
a new value can be assigned to AnotherDefaultExpr:

     void* p = AnotherDefaultExpr.take();  // design error after move  
assignment
     AnotherDefaultExpr = ParseCXXIdExpression();  // ok, just assign  
a new value

Since we anticipate clang to be regularly compiled on modern compilers  
for the foreseeable future, this lack of a compiler-generated safety  
check (with no other behavior changes) just on VC 2005 (/Za off) seems  
like an acceptable compromise to me.

-Howard




More information about the cfe-commits mailing list