Boost logo

Boost :

Subject: Re: [boost] [optional] generates unnessesary code for trivial types
From: Dave Abrahams (dave_at_[hidden])
Date: 2012-01-30 13:58:07


I support this work. Optional should be optimal :-)

on Fri Jan 27 2012, Domagoj Saric <domagoj.saric-AT-littleendian.com> 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)

Seems to me this potentially makes optional<char> much bigger. No?

> b) added another conditional constructor that accepts an in-place factory
> c) uses the safe bool idiom implementation from Boost.Range (which generates
> better code on pre MSVC10 compilers)
> d) skips redundant/dead stores of marking itself as uninitialised [including but
> limited to, in its destructor (if it has one)]
> e) streamlined internal assign paths to help the compiler avoid unnecessary
> branching
> f) added direct_create() and direct_destroy() member functions that allow the
> user to bypass the internal lifetime management (they only assert correct
> usage) in situations where the user's own external logic already implicitly
> knows the state of the optional
> g) optional now declares and defines a destructor only if the contained type has
> a non-trivial destructor (this prevents the compiler from detecting false EH
> states and thus generating bogus EH code)
> h) optional marks itself as uninitialised _before_ calling the contained
> object's destructor (this makes it a little more robust in race conditions;

I generally disagree with this sort of defensive programming. Won't it just
mask bugs?

> it is of course not a complete solution for such scenarios, those require
> external "help" and/or (m)-reference counting to be implemented)
> i) extracted the "placeholder" functionality into a standalone class (basically
> what would be left of optional<> if the lifetime management "bool" member and
> logic was removed) so that it can be reused (e.g. for singleton like classes,
> or when more complex custom lifetime management is required)
> j) added compiler specific "aids" to workaround situations when the compiler is
> unable to detect that placement new will never return a nullptr (and then
> generates bogus branching) - IOW "optional<int> optional_number( 3 );" no
> longer generates a branch before storing "3" (yes "LOL":)
> 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)
> l) removed support for antediluvian compilers (MSVC6, BCB5)
>
> todo:
>
> m) lifetime management policy: bool, pointer, reference count (+ a
> more generic abstraction/interop with smart_ptr)...
>
> n) zero size overhead for optional references (requires (m))
>
> o) avoid branching in assignment and copy construction of optionals that hold
> PODs smaller than N * sizeof( void * ) where N is some small number
>
> - temporarily renamed to optional2 to avoid collision with the original
> optional
> - passes all optional unit tests (after being renamed back to optional) with
> MSVC10 SP1 and Apple Clang 3.0 (from Xcode 4.2.1)
>
> Hope it helps ;)
>
> ps. AFAICT the only real obstacle in having really nice codegen with
> boost::optional<a_fundamental_type> is lack of proper ABI/compiler
> support for passing and returning small structs in registers...

Please tell me that at least *some* C++ compiler does that nowadays...?

-- 
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