|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2006-12-15 19:01:49
"Emil Dotchevski" <emildotchevski_at_[hidden]> writes:
> I looked in export.hpp.
>
> It seems to me that on non-metrowerks compilers it simply defines a
> namespace-scope const reference object, in a nameless
> namespace. This means that the reference is guaranteed to be
> initialized only if you execute a function in the compilation unit
> that includes export.hpp. So again, you're at the mercy of the
> optimizer to not deadstrip this code.
It is not allowed to deadstrip the code if any other code in the
translation unit gets used, because the object must be initialized
before the first use of any object or function in the TU.
> Second, even if the code is not deadstripped, you don't know when
> the registration takes place, all you know is it'll happen before
> you enter a function from the compilation unit that includes
> export.hpp. Therefore, you are still prone to threading
> problems. There is nothing in the C++ standard which guarantees
> globals will be initialized before main().
Correct.
> For Metrowerks, the code in export.hpp has this comment:
>
> // CodeWarrior fails to construct static members of class templates
> // when they are instantiated from within templates, so on that
> // compiler we ask users to specifically register base/derived class
> // relationships for exported classes. On all other compilers, use of
> // this macro is entirely optional.
>
> I don't have access to Metrowerks right now but I suspect that this has
> nothing to do with initializing static members of class templates.
I think you're wrong; I was pretty careful in my analysis.
> If I correctly recall my experience from about 2 years ago,
> Metrowers simply deadstrips the entire compilation unit, functions,
> global objects -- everything -- simply because it figures that
> nothing calls this code, and this has nothing to do with
> templates. I believe that this is correct, standard-complying
> behavior.
Yes, it is standard conforming to deadstrip the TU if nothing calls
the code, and yes, Metrowerks is really good at making that
optimization, but no, that's not what the comment is referring to.
There really is a compiler bug IIRC.
> In my opinion, the only portable option is to require manual
> registration, and leave it up to the user to come up with their own,
> non-portable solution for automatic registration, and deal with
> multi-threading/deadstripping problems this could cause. I
> personally find it easier to register my classes "manually" (note
> that systems other than the serialization library also require class
> registration.)
Yes, if you can't guarantee the TU isn't deadstripped (by guaranteeing
that it is used somehow), you need to do manual registration. On the
other hand, that was the case before I came along and made my
order-independence changes to export.hpp; I figured that the
Serialization library must have already had some way of guaranteeing
that the TU was used, and I wasn't trying to solve that problem.
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk