Boost logo

Boost :

Subject: Re: [boost] version conflicts: is there a solution?
From: Frank Mori Hess (fmhess_at_[hidden])
Date: 2009-06-28 01:33:58


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."




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