[cfe-dev] Parser Stmt/Expr Owning Pointer

Sebastian Redl sebastian.redl at getdesigned.at
Tue Dec 9 02:05:22 PST 2008


Howard Hinnant wrote:
> On Dec 8, 2008, at 9:04 PM, Chris Lattner wrote:
>
>   
>>> I personally don't find move() strange at all, but then I've been
>>> preoccupied with move semantics and their emulation since I learned
>>> of the concept two years ago. (Note: with proper C++0x moving,
>>> there'll be no need to call move() anymore. However, due to the
>>> reference binding rules of C++03, the only way to achieve this is to
>>> allow the highly unsafe practice of moving from const references.)
>>>       
>> Yep yep, rvalue refs are very nice.  Unfortunately we probably can't
>> actually *use* them in llvm/clang until they are widely deployed in
>> vendor compilers.  :(  It sucks to have to write portable code.
>>
>> What do other people think about this name?
>>     
>
> It shouldn't be surprising that I prefer move().  In fact I'd prefer a  
> namespace scope move, but I have no real problem with the member  
> move.
I'm looking forward to seeing your tricks to allow a namespace scope 
move bind to temporaries but not const lvalues. I don't know how to do 
it, so my move() is a member.
> Sebastian's ASTOwner::move() returns a ASTMove.  I'm not yet positive  
> what it will do with:
>
> {
> ASTOwner<&Action::DeleteStmt> p(actions);
> p.move();
> }  // leaked?
>   
Nope. ASTMove emulates an rvalue reference. It's patterned after 
Boost.Thread's move helper.
> And has a disadvantage that if passed to a templated function, the  
> wrong type gets deduced.
>   
True. I find the likelihood of this in the Clang source low.
> Fwiw I'm pretty close to a C++03 unique_ptr that is passing all my  
> tests so far.  It needs a <type_traits> (which I also have).  It  
> doesn't have the "moves from const" bug that my previous emulation  
> attempt had.
>   
I'd love to see it.
> template <void (Action::*Destroyer)(void*)>
> class ASTDeleter {
>    Action &Actions;
>
>    // Reference member prevents copy assignment.
>
> public:
>    explicit ASTDeleter(Action &actions) : Actions(actions) {}
>
>    void operator()(void* Node) {
>        (Actions.*Destroyer)(Node);  // no null check needed
>    }
> };
>   
Is there a specific reason the constructor can't be implicit? Then you 
could leave out the long typedef here:
>      ExprGuard ex((void*)1, ExprGuard::deleter_type(Actions));
>   
and just write ExprGuard ex(ptr, Actions).
Also, can I trick your unique_ptr to give up its raw pointer after it 
has been moved from? For convenience in the transition phase, that would 
be invaluable. In my current implementation you can do:

void takesOwnershipButHasNotBeenConvertedToBeSmart(ExprTy*);

ExprOwner ptr(getExprFromSomewhere());
takesOwnershipButHasNotBeenConvertedToBeSmart(ptr.move());

The important part is that it's always move(), even after converting the 
function to take an ExprOwner.


Sebastian



More information about the cfe-dev mailing list