From: Robert Ramey (ramey_at_[hidden])
Date: 2007-01-03 13:08:15
David Abrahams wrote:
> "Robert Ramey" <ramey_at_[hidden]> writes:
>> I don't see how one can determine at compile time whether or not an
>> object of a particular type is going to be used.
> It has nothing to do with whether an object "of a particular type" is
> going to be used; it has to do with whether objects **defined in the
> translation unit** are used.
>> In fact, it may
>> well vary from one exectution run to the next.
> So what? The compiler/linker make that determination, and for code to
> be stripped they don't need to determine precisely whether all objects
> are used or not it's sufficient for them to be able to prove that
> certain objects *won't* be used. That is sometimes provable, so
> initialization code is sometimes skipped and/or stripped.
> Can you answer the question?
> Did you intend that proper registration occur even if no objects or
> functions from the translation unit containing the EXPORT are used?
Hmmm - there are a couple of things going on which are a little confusing:
a) instantiation of code to serialize data type T with archive A. This may
(I forget the exact names) basic_archive_serializer<A, T>. It was my
this code be instantiated for all combinations of archive types and data
actually used and no others. This the fundamental function of
b) construction of an instance void_caster for each pair of types B and D
D is B is a base class of D. This is the function of ..
c) construction of an instance of extended_type_info for type T which is
used to support
So, if I make a program which loads objects of derived class D through a
base class B I will need the above described code to be instantiated even
no calls the the functions in the header containing EXPORT are explicitly
this code isn't found at runtime - due to code stripping - the program will
an "unregistered" exception. This is how it is intended to function and is
how I believe it functions on the compilers we test with.
>> So the extended type info table has to be initialized with all the
>> types that might be in the archive. This is what export attempts
>> to do.
> It doesn't do enough, and there is no portable thing it can do that
> would be enough.
Hmmm - well it does work. But I DID have to include "_export" - non
portable construct to make it work - that is the function of the
> The documentation should describe the limitations on portability of
> relying on the export code being registered even if nothing else in
> the TU is used, and should describe how to ensure that it does get
Well, that's an easy fix.
On the other hand, I don't know that all
compilers will correctly implement this behavior. For example, will
VC behave as expected when "function level linking" (which I
always use and test with) is enabled? Only testing can really
> (just call a little stub function in the TU from main()).
I can already hear the howling in the distance. If one can do this
the it would be just as easy to explcitly the all the derived types
at the beginning of an archive and avoid BOOST_CLASS_EXPORT
Then there is the question of dynamically loaded DLLS which
is involved here. Given that is is OS dependent, I expect the usage
of dynamically loaded DLLS is not portable in any case so
its easy to address just by so indicating in the documentation.
In any case, its easy to add this explanation to the documentation and
I will do this.
>> Well, that would explain one reason we've had so much problem
>> with this comipiler - its too conforming!!!
> You clearly forgot the smiley.
I'm not sure I meant that as a joke.
BTW, in the latest HEAD cw tests
there are only two tests failures (excluding a couple of failures due
to artifacts of the tests). So I'm thinking that this is going to a non
issue for all practical purposes. On the other hand, I don't think
the tests have been run with this compiler in release mode so its
not a real test. On the other hand, if this compiler has the capability
to build windows DLLS, it has to have something like the _export
keyword. Currently, force_include.hpp doesn't include anything
like this for CW but maybe it could. Note that other compilers
in wide usage (MS, Borland, GCC) all include some syntax
for addressing this issue. The header force_include.hpp
defines macros for inserting this syntax in the proper place
for each compiler. I'm surprised that no other libraries that
I know of have not had this problem. If it were more common
I would expect something like "force_include.hpp" would
be needed at the Boost level rather than the BS level.
As an aside - sort of - implementing serialization in a way which meets the
expections of most programmers - as reflected on this and the user list
could not be done without a number of contortions. I would be interesting
to consider what changes/refinements to the C++ language would be helpful in
a better system of this type. Aspects of this are in
a) extended type info - not portable external representation of a type and
not an obvious way to handle namespaces.
b) code instantiation in certain case like the above
c) sequence of intialization constructors
d) DLLS and all of the above.
e) compile time reflection
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk