|
Boost : |
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2007-01-03 13:42:30
>> 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 include
> (I forget the exact names) basic_archive_serializer<A, T>. It was my
> intention that
> this code be instantiated for all combinations of archive types and data
> types
> actually used and no others. This the fundamental function of
> BOOST_CLASS_EXPORT
How does BOOST_CLASS_EXPORT help me if I have my own archive serializer?
Even if I'm using one of the archives the library provides for me, I think
that it is unreasonable to automatically register all combinations of
archivers and types because it introduces physical coupling between
translation units which don't depend on each other (in a program where only
one archive type is used, which is typical.)
> b) construction of an instance void_caster for each pair of types B and D
> where
> D is B is a base class of D. This is the function of ..
> BOOST_SERIALIZATION_BASE_OBJECT_NVP
>
> c) construction of an instance of extended_type_info for type T which is
> used to support
> the above.
>
> So, if I make a program which loads objects of derived class D through a
> pointer to
> base class B I will need the above described code to be instantiated even
> though
> no calls the the functions in the header containing EXPORT are explicitly
> made.
This discussion is not about whether or not we need those templates to be
instantiated; of course we do.
>>> 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
> "force_include.hpp"
> header.
It does work until it doesn't. In several projects I have worked on, I have
seen similar systems relying on "auto registration" to fail due to seemingly
unrelated changes in the code base, or when the code is ported to another
operating system or platform. The only compiler I have observed to not
deadstrip such code consistently is MSVC.
I still think that whether it works or not is irrelevant if the documented
behavior can not be delivered within the limits of the C++ standard. In my
mind it only works because the compiler is not smart enough.
>> 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
>> registered
>
> 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
> resolve this.
This is true for any provision in the standard that is optional, or
behaviors that are "implementation defined". I don't think it is a good idea
to rely on implementation-defined behavior. If we insist that we rely on it,
we should clearly state that the behavior is not portable and has only been
tested on such and such compilers/platforms.
In my opinion the "auto registration" should be removed from the
serialization library altogether, and replaced with an example demonstrating
how it could be done, provided that your compiler doesn't dead strip this
kind of code even though it is allowed to.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk