Boost logo

Boost :

Subject: Re: [boost] [interprocess] default constructors
From: David Abrahams (dave_at_[hidden])
Date: 2008-12-04 13:59:50


on Wed Dec 03 2008, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:

> Mathias Gaunard wrote:
>> The overhead I'm talking about is that allowing an empty state in the object might
>> have a cost.
>>
>> A simple example is that if you have a function release(resource&), that releases a
>> valid resource, and you want to wrap that resource using RAII, you have to write the
>> destructor as
>>
>> if(!is_empty)
>> release(res);
>>
>> instead of simply
>>
>> release(res);
>>
>> So you need to maintain a boolean (size overhead) and perform a branching (runtime
>> overhead).
>>
>> Usually, however, at least the size overhead can be eliminated since there is a
>> special resource value reserved for the null resource.
>
> You are right. My point is that if you want to support a movable object:
>
> {
> non_copyable_file_descriptor fd("filename");
> non_copyable_file_descriptor fd2(move(fd));
> //Both destroyed here
> //fd2 closes the file descriptor
> //fd is "empty"
> }
>
> you need to encode the "empty" state. Making the default constructor
> public or not is not the point. If we want to support non-destructible
> move-semantics we will always have this overhead in destructors.

It is true that we need an empty state for move semantics. However, the
appearance of said state can naturally be restricted to situations where
the object is about to be either destroyed or assigned, which means that
it's reasonable to say that the object's other operations are only
available when the state isn't empty. It's somewhat less-reasonable to
say that other operations are unavailable for empty objects when the
empty state is available via a constructor (although the built-ins do
it). I know it's a little wishy-washy, but I think limiting
construction to producing fully-capable objects can still be valuable
even in the face of an empty state introduced for move semantics.

> There is a proposal to optimize these destructors:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2754.html
>
> N2754: "Additional concepts: TriviallyDestructibleAfterMove and
> TriviallyReallocatable"
>
> This will be very useful in containers, but I'm just thinking if compilers could be
> smart enough to avoid calling destructors for moved objects if the are
> TriviallyDestructibleAfterMove:
>
>
> {
> //non_copyable_file_descriptor is
> //"TriviallyDestructibleAfterMove":
> non_copyable_file_descriptor fd("filename");
> non_copyable_file_descriptor fd2(move(fd));
> //Both destroyed here
> //fd2 closes the file descriptor
> //The compiler bypasses fd's destructor
> }

That would be kewl.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk