Boost logo

Boost :

Subject: Re: [boost] [optional] generates unnessesary code for trivial types
From: Domagoj Saric (domagoj.saric_at_[hidden])
Date: 2012-02-02 10:18:49


On 1.2.2012. 17:53, Hite, Christopher wrote:
>> On 27.1.2012. 11:32, Domagoj Saric wrote:
>
>> a) the lifetime management bool was changed into a properly typed pointer (this
>> actually takes the same amount of space while it provides a no-op get_ptr()
>> member function as well as easier debugging as the contents of optional can
>> now clearly be seen through the pointer, as opposed to gibberish in an opaque
>> storage array)
> I'd support this only if were configurable. It takes more space for small or
> non-word-aligned data.

True, I was planning on automatically deciding between bool and pointer based on
sizeof( T ) after adding lifetime management policy support (m)...

> It might be more expensive on some systems to calculate
> the address and store it.

How? You have to fetch the address either way...

> It would also break has_trivial_copy. If someone was naughty and memcopied them,
> the new version would lead to a very hard to find bug.

True, didn't think about trivial copy until Sebastian outlined the
pass-POD-in-register requirements of the AMD x64 ABI. WRT to this it boils down
to whether you want a no-op get_ptr() or your platform and compiler actually
support passing PODs in registers _and_ most of the types you store in optionals
actually satisfy the compiler/ABI requirements for that _and_ you mostly pass
and return those optionals by value...

> As for the debugger the new C++ allows for a union to contain a class. So if
> a placeholder implemention using such a union would show the data in debug.

But the pointer approach would also work with "real world" compilers ;)

>> h) optional marks itself as uninitialised _before_ calling the contained
>> object's destructor (this makes it a little more robust in race conditions;
>> it is of course not a complete solution for such scenarios, those require
>> external "help" and/or (m)-reference counting to be implemented)
> Seems to contradict (g). I'd support something like that only if it can be
> configured out. Maybe there's some case completely out of optional's scope
> where you use atomic ops.

It doesn't (contradict (g)), this applies only to situations where you actually
have to mark the optional as empty (such as when reset() is called).

> If you factor out the aligned storage you can build something else that does
> ref-counting or a thread safe state machine or whatever.

With (m) I'd rather (in some distant future:) add a refcounting policy to
optional (or some future underlying more generic class) so that users don't have
to reimplement this...

>> k) the lifetime management pointer is now stored after the actual contained
>> object (this helps in avoiding more complex/offset addressing when accessing
>> optionals through pointers w/o checking whether they are initialised)
> Seems weird. If the front of T is more likely to be used (and old char buffer),
> your pointer may wind up in a different cache line.

Well yes, as I said this benefits only the cases where the pointer/bool is not
accessed (when an optional is accessed through a pointer/reference). IOW in
99.9% of real world cases the point is quite moot but it did make sense at a
particular stage of a project I'm working on (when you have dozens of hundreds
of template generated functions you can actually measure savings in code size
when you do even such micromanagement). It no longer matters for me but the
layout of optional2 is still like that (currently) purely because it turned out
like that (in the current stage of development) so I wrote point (k) nonetheless
just for the feedback ;)

> So the big thing I take away from all this it would be really nice if some things
> were configurable. How do we do that without breaking code?
>
> Changing the signature to optional<T,Properties=optional_traits<T> >, might
> break code that uses boost::optional as a template template parameter.

Judging for example from the rationale for the lack of smart_ptr configurability
or from the feedback I got for my improved boost::function proposal, it would be
very difficult for this type of configurability for optional to get accepted.

I was rather planing on making the best of optional with automatic/self
configuration based on properties of T and then later (in a galaxy far far
away:) propse an underlying library ("smart resource" or something like that),
that would separate the lifetime management and storage concerns in a maximally
configurable manner, on top of which traditional optional smart_ptr could be
built...

-- 
"What Huxley teaches is that in the age of advanced technology, spiritual
devastation is more likely to come from an enemy with a smiling face than
from one whose countenance exudes suspicion and hate."
Neil Postman

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