|
Boost : |
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2007-03-21 14:03:59
>> There is another warning which is missing from the documentation:
>> portable code can not rely on BOOST_CLASS_EXPORT to register a class
>> unless the user explicitly calls a function from a compilation unit
>> that "sees" that particular BOOST_CLASS_EXPORT call. This is because
>> it relies on a global object's constructor to initiate the
>> registration process, but a good compiler will deadstrip all such
>> global objects unless the user explicitly calls a function from the
>> compilation unit that defines them.
>> In other words BOOST_CLASS_EXPORT isn't automatic because a portable
>> program is required to (manually) call a (possibly empty) function
>> from the registered class' cpp file. This is contradictory to
>> BOOST_CLASS_EXPORT's intended use to register derived classes
>> automatically, just by linking their cpp files.
>
> I don't think that's currently true - if it ever was. The code
> specifically
> addresses this issue with a number of compiler specific adjustments
> to insure that code is not stripped. These adjustments have proved
> effective for all compilers/linkers that boost supports (with the possible
> exception of CodeWarror). So maybe its true were the system
> compiled on a strickly comformant compiler which has no extensions
> to prevent code stripping, but as far as I know, there is no
> such compiler being used. I also believe that its unlikely that
> any such compiler/combination will ever see the light of day since
> it would be useless for building DLLs (shared libraries).
The key word in my statement is portable. I know there are non-portable
workarounds on most compilers, but next versions of these same compilers
could require a new workaround, and the standard tells you that such
workaround may not be possible.
Preventing a global object from being deadstripped still does not guarantee
that it will be initialized before you call a function from its compilation
unit. Suppose you have a global object that allocates a lot of memory, this
provision in the standard allows the compiler to postpone this allocation
until it is actually needed.
In several large code bases I have spent many hours fighting with this same
issue of various registration schemes being deadstripped because they rely
on a global object to boot. In fact what prompted my post is that I'm
currently having the same problem with a popular 3D engine. I have to dig
through all of their macro trickery, static class members and whatnot, to
figure out what needs to be initialized -- It's very frustrating, and by far
outweights any benefits of their "automatic" registration.
I think that no harm would be done if the documentation states that
BOOST_CLASS_EXPORT relies on compiler-specific tricks and is not portable.
This is especially important for a Boost library.
Emil Dotchevski
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk