|
Boost : |
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2006-12-15 14:14:54
> Emil Dotchevski wrote:
>> However I don't see how this can be done automatically. I suppose
>> you're using some kind of global object to do the registration
>> (because you say
>> it's done on startup). However, the global object isn't guaranteed to
>> be initialized at startup, all you know is that it will be
>> initialized before you enter any function from foo.cpp.
>
> I didn't see how to do this either. Dave Abrahams finally did it. Look
> in export.hpp
>
>> In fact I have seen Metrowerks (correctly) consider a similar
>> "automatic" registration dead code and remove all foo.cpp code from
>> the executable (not just the global object, the entire class foo is
>> removed.)
>
> I notice that export.hpp has some special code for Metrowerks - maybe
> that's related to your point.
>
> Look in export.hpp
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.
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().
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. 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.
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.)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk