Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-02-01 22:39:00


"David B. Held" <dheld_at_[hidden]> writes:

> "David Abrahams" <dave_at_[hidden]> wrote in message
> news:ud6mbd2f5.fsf_at_boost-consulting.com...
>> [...]
>> Up to a point. I know MWerks is object-compatible in the
>> single-inheritance case (for the sake of COM and MFC), but not
>> if there's MI. However, they still have MI EBO problem.
>>
>> Further, this is not a Win32-specific problem. Most Unix compilers
>> that aren't GCC-3.x have it as well, AFAICT.
>
> So in your opinion, *ought* the optimally_inherit solution to work
> even on these compilers?

If you don't care about ctors and dtors, it sounds plausible, but
there's no reason in principle that they shouldn't have the same
problems you cite below for VC++. You never know with some of them,
though. Borland is particularly strange about layout.

>> [...]
>> I guess that's OK if you don't care how many ctors and dtors get
>> called. The lifetimes of these temporaries obviously won't mirror
>> that of the smart_ptr. Sounds like a fragile arrangement to me.
>
> I imagine that the temporaries won't get created at all,

Whaaa? A temporary that never gets created?

> since their sole purpose is to verify policy compatibility. In the
> majority of cases, they will simply call an appropriate copy c'tor,
> which will be trivial or generated, because the class has no state.

Maybe you should illustrate what you mean, 'cause I'm lost.

>> If you only inherit from non-empty bases, how is EBO relevant at
>> all?
>
> That's a very good question. Maybe I should call it an "Empty
> Derived Optimization" problem. For some reason, even in this
> configuration, VC++ insists that sizeof(smart_ptr) > 8:
>
> class smart_ptr
> : optimally_inherit<
> optimally_inherit<storage, checking>,
> optimally_inherit<ownership, conversion>
> >
> { ... }

Since I can't see what's in the bases nor any of smart_ptr's data
members here, it's hard to know how to interpret sizeof(smart_ptr) > 8
or whether it's even a problem [but I get it below].

> I can prove that optimally_inherit<storage, checking> only derives
> from storage, and similarly for ownership with a simple test case.
> So why VC++ thinks it needs to inflate the size of smart_ptr is
> beyond me. But it isn't just smart_ptr. It inflates the size of the top-
> level optimally_inherit, which is inheriting from two non-empty base
> classes. Perhaps we should call it the "Non-emtpy Base MI
> Pessimization" (NoBMIP)?

OK, I get the picture now.

> I assumed it was because it didn't want any of the bases to share an
> address with the derived class, which is analogous to the EBO case.
> But perhaps I misunderstand what is going on, and you can shed some
> light on it for me.

I don't think I can do any better than you. I have the same tools at
my disposal. I'd do a bunch of experiments and look at the resulting
class layouts by checking the size and the relative addresses of
members.

>> [...]
>> > I know that optimally_inherit *does* work under VC++ for some
>> > cases. I just don't know exactly what those cases are, and I don't
>> > really want to spend a week trying to discover it, especially as that
>> > won't help people who are writing custom policies.
>>
>> Why not?
>
> Well, suppose that I discover *some* configuration in which EBO and
> optimally_inherit produce the desired size, but I don't know *why*
> that configuration has the desired result. How is a user to know if
> his custom policy is going to kill EBO again or not, based on the
> working configuration?

You could probably figure out the VC++ algorithm by experimentation,
but that still wouldn't help a user trying to write portable,
efficient code, unless you find a workaround for every other compiler.

-- 
                       David Abrahams
   dave_at_[hidden] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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