
Robert Ramey wrote:
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.
I recall that I did suggested one approach. BOOST_CLASS_EXPORT can register the class with all previously included archives and, unconditionally, with polymorphic archive. During saving, you can check if the saved class is registered with specific archive type. If not, you wrap archive in polymorphic archive and save. That would be slower, but in most situation extra virtual function call won't be a practical problem. In the rare case where it will be a problem, user can: 1. Include necessary archive headers 2. Invoke BOOST_CLASS_EXPORT *again* in his module, after including another archive header. If BOOST_CLASS_EXPORT tolerates multiple invocations, this will instantiate the code for the needed archive type, and make saving to that archive type go without polymorphic arhive.
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.
I never understood this. BTW, did you have a chance to try my ADL patch?
"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.
Sorry, it might turn into a long thread after all, because you haven't still answered the attached message of mine. To summarize, I claim that the rule immediately prevents the "include my own headers right at the top" practice that I use. - Volodya