From: Robert Ramey (ramey_at_[hidden])
Date: 2005-07-05 13:02:24


Edward Diener wrote:
> I made a similar point about #include order dependency and the
> serialization library in this NG, but my point was that the creator
> of a library can always make sure that a particular header file is
> included
> if necessary, through checking #defines, and that the end user should
> never have to worry about header include order.
>
> I think this is really important from an end-user's point of view. I
> do
> not believe that any library in which, from the end-user's
> perspective, header files have to be included in a particular order
> can be really
> robust, even though I know that this is sometimes done in some famous
> situations.
>
> Regarding the particular situation explained above, I would much
> rather
> that the end-user have to #define a macro for a particular file in
> order
> to load a previously archived object from an earlier version, if that
> is
> what it takes, than that he/she need to include header files in a
> particular order.
>
> Header file order dependencies, from an end-user's perspective, are a
> minefield it is best to avoid at all costs.

Well, that would be my preference, but in some cases its unavoidable. In
the serialization library I've got a couple of situations:

export.hpp:

the function of BOOST_CLASS_EXPORT("classname") is to instantiate code for
the particular class for all archives used. The list of all archives used
is built from looking at the guard macros from previously seen *archive.hpp
files. This permits instantiations to be limited to those *archive classes
actually used whose declarations have actually been included. That
alternative to this would be to instanciate code for all archives - which
would make programs much bigger and take much longer to compile.

two-phase lookup:

In general, the existence of two-phase lookup can alter the symantics of the
program depending on header order. I believe that this can be addressed
with partial template specialization but not all compilers supported by the
serialization library support this. This resulted in a bunch of quirky and
non-obvious rules about which namespace to put serialization specializations
in - see the 1.32 documentation. The rules depended on whether or not
partial template specialization was supported. So the stl serialzation was
filled with alot of #ifdef ... . By adhereing to the rule that all
*archive.hpp headers come before all *serialization headers all these
problems were resolved.

typeinfo_implementation.hpp

The serialization system needs a system for handling the type of data at
runtime. During the review, there was one reviewer who made a point that
RTTI should not be required. I wasn't really convinced but it turned out I
had to make a thing called extended_type_info which supplemented the
functionality of RTTI by adding GUID (globally unique identifier - a string
constant). As I worked on this, I was able to factor out the implementation
of this so that in fact I wasn't really tied to RTTI to implement it. The
result was that the system permits one to plug-in his own preferred
extended_type_info implemention. This is tested and demoed in test_no_rtti.
So far so good. Now it turns out that no one really uses this facility as
the RTTI one is more convenient. So I implemented the idea that if no
type_info system has been #included, #include the
extended_type_info_typeid.hpp one as a default.

So, that is how things arrived at the current situation. As I said, it
wouldn't be my first choice, but I find it much preferable to the
alternatives. So I imposed the rule:

"all <boost/archive/...> should be listed before all the
<boost/serialization/...> includes"

Its very easy to remember and is enforced by and #error ... if the rule is
violated. It does inhibit the mixing of <boost/archve/..> and
<boost/serialization/..> includes other header modules. But in view this
should never be done anyway as doing so compromises the orthogonality of the
<boost/serialization/..> and <boost/archive/..> headers which is a key
concept of the library implementation.

I'm sitting here hoping against hope that this will not turn into another
very long thread.

Robert Ramey