From: Robert Ramey (ramey_at_[hidden])
Date: 2006-12-16 18:08:06
David Abrahams wrote:
> "Robert Ramey" <ramey_at_[hidden]> writes:
>> David Abrahams wrote:
>>> "Emil Dotchevski" <emildotchevski_at_[hidden]> writes:
>>>> Or did I completely misunderstand the documentation? Robert, was
>>>> the intended meaning that *if* you explicitly call a function from
>>>> foo.cpp, then using the class export macro guarantees that class
>>>> foo is properly registered with the serialization library?
>> My intention is and was that proper registration will occur whether
>> or not the type is explicitly referred to.
> "Whether the type is explicitly referred to" is completely irrelevant.
> The question is whether any objects or functions from the translation
> unit containing the EXPORT are used.
> Did you intend that proper registration occur even if no objects or
> functions from the translation unit containing the EXPORT are used?
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. In fact, it may well
vary from one exectution run to the next. The situation I had in
mind is that of serialization of derived through an abstract base class.
suppose one is going to load an archive. The sequence of events is
a) read the export tag
b) look it up in the extended type info table
c) using this pointer, lookup the deserializer function
d) and invoke them
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. But when compiled for release mode, some compilers
drop the deseralization code. The results in a run time error
"unregistered type". I always interpreted this as the
compilers droping code that was never explicitly called. This
is what occurs when we have an executable or dll which
contains entry points never called. Some compilers provide
the keyword "__export" to tell the compilers that such functions
shouldn't be dropped even though they don't seem to be called.
So I used these to be sure the the specified code didn't get
dropped. Perhaps I should have described this but
>> That was my goal and I believe it has been achieved for all
>> compilers that boost supports.
> I would be very surprised if that were the case for Metrowerks; as
> pointed out by Emil, that compiler is very good at optimizing out
> unused translation units.
Well, that would explain one reason we've had so much problem
with this comipiler - its too conforming!!!
>> In order to accomplish this I resorted to compiler specific syntax
>> not described by the standard.
> Not for every compiler... and there is no guarantee that the next
> version of GCC or MSVC won't apply the optimization more aggressively.
>> Now it seems the question being raised is whether this is/was the
>> right thing to do.
> No, I don't think that is the question at all, at least, not mine. My
> question is what promises you can legitimately make to users about
> what will happen, and whether you have made your promises sufficiently
> That's a legitimate thing to do, but I think you need to be very
> explicit about what you're doing.
Well, that's easy to fix. I guess that all we need to say is:
a) functionality of export cannot be guarenteed to be made to work
on all compilers.
b) If you want your code to be guarenteed to be portable to other
compilers, don't use export - use explicit registration instead.
>Do any of your tests actually exercise the
> case where the EXPORT is in a TU with no used functions or objects?
Well, I thought demo_pimpl did this - but I looked at it and it doesn't
So I checked test_exported. Its only one translation unit so it doesn't
explicitly test this situation - the derived class constructor is called
explicitly. this could easily be moved to another *.cpp file to test
I did find one thing that was new to me and very interesting:
// MWerks users can do this to make their code work
which I had never seen before. I don't know if this is related in some way.
>> - its just not guarenteed to be portable to new compilers.
> Or new versions of existing compilers.