
On Saturday 27 June 2009, Ilya Bobir wrote:
Unless your "user-defined library" include headers you can not introduce names into a translation unit.
I think you left out a word or something, that sentence wasn't quite coherent.
And even if it does include headers the ODR applies only to the stuff you have in that headers and not to the "rest" of the library.
Not sure what that sentence means either.
It means that unless you have the Boost headers somewhere in the header part of your library there is no way to violate the ODR as it applies to the translation units only.
Nonsense. Two translation units can conflict with each other and violate the one definition rule without having to contain any common header files. And just because one translation unit came from a library instead of "your" code doesn't make it any less a part of the final program, or make the one definition rule apply any less to it. There's nothing in the one definition rule about exceptions to the rules for "translation units that are separated by a library boundary from which internal symbols have been stripped, etc, etc...". The relevant part to multiple definitions residing in separate translation units is paragraph 5 of section 3.2 (as I've mentioned twice before but I'll quote it this time): "There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template special- ization for which some template parameters are not specified (14.7, 14.5.4) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following require- ments. Given such an entity named D defined in more than one translation unit, then — each definition of D shall consist of the same sequence of tokens; and — in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a const object with internal or no linkage if the object has the same integral or enumeration type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D; and — in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and — in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if its token sequence were present in the definition of D; that is, the default argument is subject to the three requirements described above (and, if the default argument has sub-expressions with default arguments, this requirement applies recursively).25) — if D is a class with an implicitly-declared constructor (12.1), it is as if the constructor was implicitly defined in every translation unit where it is used, and the implicit definition in every translation unit shall call the same constructor for a base class or a class member of D. [Example: // translation unit 1: struct X { X(int); X(int, int); }; X::X(int = 0) { } class D: public X { }; D d2; // X(int) called by D() // translation unit 2: struct X { X(int); X(int, int); }; X::X(int = 0, int = 0) { } class D: public X { }; // X(int, int) called by D(); // D()’s implicit definition // violates the ODR —end example] If D is a template, and is defined in more than one translation unit, then the last four requirements from the list above shall apply to names from the template’s enclosing scope used in the template definition (14.6.3), and also to dependent names at the point of instantiation (14.6.2). If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined."