From: David Abrahams (dave_at_[hidden])
Date: 2003-02-03 00:01:33
"David B. Held" <dheld_at_[hidden]> writes:
> "David Abrahams" <dave_at_[hidden]> wrote in message
> But the compiler knows this too. So if the c'tor and d'tor are both
> trivial, why not just optimize them away?
AFAICT you're conflating two things, the EBO and optimization of
trivial ctors and dtors. From what you told me, optimally_inherit
removes empty classes from smart_ptr's bases. If the ctors and dtors
of these classes are trivial, of course they'll be optimized away.
The problem arises if the user passes an empty policy class with
non-trivial ctor or dtor: then the fact that it's being
constructed/destructed at different times from the rest of the bases
will have visible effects.
>> If that's all you care about you could just do
> Does this work reliably on all platforms? If so, that is a better
Everything I know of but CWPro7, which is outdated. I would just
sacrifice checking in some circumstances for that platform.
>> > But no_check has no such conversion c'tors, because presumably,
>> > one does not want to *reduce* the level of checking. Since the
>> > checking policies generally don't have any state, the c'tors are all
>> > trivial, and hopefully, will get optimized out of existence. They
>> > merely serve as a compile-time check of compatibility.
>> I've been concerned about optimizing storage, not code. The EBO
>> issue has nothing to do with inlining constructors.
> Right. I was just explaining why I was creating temporaries in the first.
> place. You said:
>> If you don't care about ctors and dtors, it sounds plausible,
> which I took to mean that you thought having extra c'tor/d'tor calls
> for optimally_inherit would make things fatter/slower. I was just
> trying to argue that I expected most of it to get optimized away.
No, I was trying to say that your the space optimzation you're trying
to achieve via optimally_inherit will have visible effects on the
behavior of the smart_ptr, because the non-trivial ctors and dtors of
the empty (non-)"bases" will run at different times.
>> > [...]
>> > Yeah, that's the problem. :( Even more disturbingly, it's not clear if
>> > this is just an MI problem, or a problem with inheritance in general
>> > with VC++. I mean, when I tried the chained policy implementation,
>> > it did provide the right size, but that doesn't mean it won't change if
>> > I update the implementation (and that version would require a lot of
>> > changes to get it up to speed with the MI version).
>> I've been saying this over and over: yes it does, for all practical
>> purposes. Vendors are VERY reluctant to break object code
>> compatibility. If they ever do break it intentionally, it will only
>> be to do *more* optimizations, not fewer.
> Maybe I wasn't clear.
Sorry. When you said "update the implementation" I thought you meant
"switch to a new compiler version".
> it seems conceivable to me that there might exist some
> configurations of the chained policy setup in which the
> sizeof(smart_ptr) gets inflated for some inexplicable reason (unless
> you know for sure this won't happen).
I do not. However, the set of scenarios (strict single inheritance
chains only) is a much more-limited case, and I'm pretty sure you can
satisfy yourself that you understand the choices VC++ makes in that
case by running a few experiments.
> So the fact that the first version of the chained policy gave sizeof
> == 8 doesn't give me confidence that *every* version of the chained
> policy will have the desired property. For all I know, adding a
> certain number of member functions to some policy will cause VC++ to
> decide that now it's going to make sizeof(smart_ptr) == 12 or 16 or
> whatever number it likes.
It's possible, but you don't yet have a single case of that you can
point at, whereas you have quite a few cases of EBO failure in the MI
case. I would be going with an organization that has never failed to
be "tight" rather than trying to trick the compiler into tightening an
organization that commonly bloats.
Some things you can do to help with the single-inheritance chain: put
classes that are likely to have members near the root of the chain, so
that successive derived classes don't add any members. That way, even
the single-inheritance EBO is not needed to get optimal size. This is
a natural organization for the cases you've been talking about, and it
works for the EH too.
> It would be nice to have some assurance that this won't happen, but
> the current state of affairs with the MI setup doesn't exactly
> involve EBO
I don't know what you mean by that.
> , and so I'm afraid that the chained policy configuration might be
> susceptible to the same fate.
-- 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