Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2007-01-04 10:39:08


"Robert Ramey" <ramey_at_[hidden]> writes:

> David Abrahams wrote:
>> "Robert Ramey" <ramey_at_[hidden]> writes:
>>
>>> All combinations of A and T actually used - and only those
>>> combinations - are used to instantiate code.
>>
>> I don't think that can be true for any reasonable definition of
>> "used." Code in one TU can't tell what other TUs are doing, so the
>> code is instantiated for all archives whose headers have been
>> included. IIRC it gets around the ordering problems you were having
>> before by doing the instantiation as the result of overload resolution
>> on an unqualified call, which happens in phase 2 and thus doesn't
>> depend on having seen the overload for a particular archive type
>> before the serializable type is EXPORTed. It doesn't do any other
>> deep magic, IIRC.
>
> After I thought about this some more I've also come to agree with this.
>
> So the above would be better said
>
> All combinations of A and T actually used - and only those
> combinations - are used to instantiate code - in a transation
> unit with at least one function called from either directly or
> indirectly from main.

Sorry, I don't think that's an accurate statement of anything. This
is accurate:

   In a given translation unit (TU), all combinations of A and T,
   where A is an archive registered (in the TU) with
   BOOST_SERIALIZATION_REGISTER_ARCHIVE and T is a class exported (in
   the TU) with BOOST_CLASS_EXPORT(**) are used to instantiate
   polymorphic pointer serialization code. Period.

   The translation unit or some portion of it may later be discarded
   if the linker can prove none of its functions or objects are used,
   or else its initializers may be skipped. Separate issue.

In more detail: each time you use
BOOST_SERIALIZATION_REGISTER_ARCHIVE, it instantiates pointer
serialization for that archive in combination with all
BOOST_CLASS_EXPORTed types, and vice versa: each time you use
BOOST_CLASS_EXPORT, it instantiates pointer serialization for that
class in combination with all BOOST_SERIALIZATION_REGISTER_ARCHIVEed
archives. In a TU where the uses of these macros do not appear, no
such instantiation takes place. By the way, my earlier explanation of
the use of phase 2 lookups was inaccurate. The mechanism I describe
in this paragraph doesn't depend on (and indeed, can't use) phase 2
lookups.

(**) **PLEASE** be a good Boost citizen and change that name to
     BOOST_SERIALIZATION_EXPORT_CLASS!! The meaning of "exporting a
     class" cannot remain reserved by the serialization library
     throughout Boost. It's too general a description of things that
     many libraries will want to do, and while Boost.Serialization is
     important, it's not more important than every other library that
     might want to "export a class."

> I never really picked up on this. This is probably because all
> but a couple of tests to be only one module long. I suspect
> that were I to modify one of export tests - it would fail in
> release mode in one or another of the compilers. But maybe
> not. The inclusion of "force_include.hpp" and corresponding
> usage of "_export" will probably guarentee that the compiled
> code is never stripped. So the problem may never be manifested
> in such a test.
>
> question: does the CW compiler include something like "_export"
> in order to compile windows (or *nix?) DLLS (shared libraries)?

I don't know. I'm sure there are online docs somewhere.

> question:what if anything does the standard say about something
> like "_export" which is necessary in order to communicate that
> the corresponding code should never be stripped?

Nothing; it's a pure extension.

> I've been under the impression that
>
> a) "_export" is not portable
> b) "_export" or something like is necessary to supress code stripping
> c) suppression of code stripping is necessary in order to make a DLL

When making a DLL, the linker is free to decide not to strip anything.
DLLs are outside the standard (a pure extension), and the standard
doesn't mandate any stripping anyhow.

> which would imply that in order to produce a DLL, a compiler must
> be non-conforming - or at least support non-corformant behavior.
>
> Am I missng something here?

Yeah, there's no law that says a linker ever has to strip anything.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk