6 Basics [basic]

6.3 One-definition rule [basic.def.odr]

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, template, default argument for a parameter (for a function in a given scope), or default template argument.
An expression or conversion is potentially evaluated unless it is an unevaluated operand ([expr.prop]), a subexpression thereof, or a conversion in an initialization or conversion sequence in such a context.
The set of potential results of an expression e is defined as follows:
• If e is an id-expression, the set contains only e.
• If e is a subscripting operation with an array operand, the set contains the potential results of that operand.
• If e is a class member access expression ([expr.ref]) of the form e1 . template e2 naming a non-static data member, the set contains the potential results of e1.
• If e is a class member access expression naming a static data member, the set contains the id-expression designating the data member.
• If e is a pointer-to-member expression ([expr.mptr.oper]) of the form e1 .* e2, the set contains the potential results of e1.
• If e has the form (e1), the set contains the potential results of e1.
• If e is a glvalue conditional expression, the set is the union of the sets of potential results of the second and third operands.
• If e is a comma expression, the set contains the potential results of the right operand.
• Otherwise, the set is empty.
Note
:
This set is a (possibly-empty) set of id-expressions, each of which is either e or a subexpression of e.
Example
:
In the following example, the set of potential results of the initializer of n contains the first S​::​x subexpression, but not the second S​::​x subexpression.
struct S { static const int x = 0; };
const int &f(const int &r);
int n = b ? (1, S::x)           // S​::​x is not odr-used here
: f(S::x);            // S​::​x is odr-used here, so a definition is required
— end example
]
— end note
]
A function is named by an expression or conversion as follows:
• A function is named by an expression or conversion if it is the unique result of a name lookup or the selected member of a set of overloaded functions ([basic.lookup], [over.match], [over.over]) in an overload resolution performed as part of forming that expression or conversion, unless it is a pure virtual function and either the expression is not an id-expression naming the function with an explicitly qualified name or the expression forms a pointer to member ([expr.unary.op]).
Note
: This covers taking the address of functions ([conv.func], [expr.unary.op]), calls to named functions ([expr.call]), operator overloading ([over]), user-defined conversions ([class.conv.fct]), allocation functions for new-expressions, as well as non-default initialization ([dcl.init]). A constructor selected to copy or move an object of class type is considered to be named by an expression or conversion even if the call is actually elided by the implementation ([class.copy.elision]). — end note
]
• A deallocation function for a class is named by a new-expression if it is the single matching deallocation function for the allocation function selected by overload resolution, as specified in [expr.new].
• A deallocation function for a class is named by a delete-expression if it is the selected usual deallocation function as specified in [expr.delete] and [class.free].
A variable x whose name appears as a potentially-evaluated expression e is odr-used by e unless
• x is a reference that is usable in constant expressions ([expr.const]), or
• x is a variable of non-reference type that is usable in constant expressions and has no mutable subobjects, and e is an element of the set of potential results of an expression of non-volatile-qualified non-class type to which the lvalue-to-rvalue conversion ([conv.lval]) is applied, or
• x is a variable of non-reference type, and e is an element of the set of potential results of a discarded-value expression ([expr.prop]) to which the lvalue-to-rvalue conversion is not applied.
A structured binding is odr-used if it appears as a potentially-evaluated expression.
*this is odr-used if this appears as a potentially-evaluated expression (including as the result of the implicit transformation in the body of a non-static member function ([class.mfct.non-static])).
A virtual member function is odr-used if it is not pure.
A function is odr-used if it is named by a potentially-evaluated expression or conversion.
A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class.
A non-placement deallocation function for a class is odr-used by the definition of the destructor of that class, or by being selected by the lookup at the point of definition of a virtual destructor ([class.dtor]).21
An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified in [class.copy.assign].
A constructor for a class is odr-used as specified in [dcl.init].
A destructor for a class is odr-used if it is potentially invoked.
A local entity ([basic]) is odr-usable in a declarative region ([basic.scope.declarative]) if:
• either the local entity is not *this, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and
• for each intervening declarative region ([basic.scope.declarative]) between the point at which the entity is introduced and the region (where *this is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), either:
If a local entity is odr-used in a declarative region in which it is not odr-usable, the program is ill-formed.
Example
:
void f(int n) {
[] { n = 1; };                // error: n is not odr-usable due to intervening lambda-expression
struct A {
void f() { n = 2; }         // error: n is not odr-usable due to intervening function definition scope
};
void g(int = n);              // error: n is not odr-usable due to intervening function parameter scope
[=](int k = n) {};            // error: n is not odr-usable due to being
// outside the block scope of the lambda-expression
[&] { [n]{ return n; }; };    // OK
}
— end example
]
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.
The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.default.ctor], [class.copy.ctor], [class.dtor], and [class.copy.assign]).
A definition of an inline function or variable shall be reachable in every translation unit in which it is odr-used outside of a discarded statement.
Example
:
auto f() {
struct A {};
return A{};
}
decltype(f()) g();
auto x = g();
A program containing this translation unit is ill-formed because g is odr-used but not defined, and cannot be defined in any other translation unit because the local class A cannot be named outside this translation unit.
— end example
]
A definition of a class is required to be reachable in every context in which the class is used in a way that requires the class type to be complete.
Example
:
The following complete translation unit is well-formed, even though it never defines X:
struct X;                       // declare X as a struct type
struct X* x1;                   // use X in pointer formation
X* x2;                          // use X in pointer formation
— end example
]
Note
:
The rules for declarations and expressions describe in which contexts complete class types are required.
A class type T must be complete if:
— end note
]
There can be more than one definition of a
in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
There shall not be more than one definition of an entity that is attached to a named module ([module.unit]); no diagnostic is required unless a prior definition is reachable at a point where a later definition appears.
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, where the definition of a closure type is considered to consist of the sequence of tokens of the corresponding lambda-expression; and
• in each definition of D, corresponding names, looked up according to [basic.lookup], shall refer to the same entity, after overload resolution ([over.match]) and after matching of partial template specialization ([temp.over]), except that a name can refer to
• a non-volatile const object with internal or no linkage if the object or
• a reference with internal or no linkage initialized with a constant expression such that the reference refers to the same entity in all definitions of D;
and
• in each definition of D, except within the default arguments and default template arguments of D, corresponding lambda-expressions shall have the same closure type (see below); and
• in each definition of D, corresponding entities shall have the same language linkage; 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; and
• in each definition of D, a default argument used by an (implicit or explicit) function call or a default template argument used by an (implicit or explicit) template-id or simple-template-id is treated as if its token sequence were present in the definition of D; that is, the default argument or default template argument is subject to the requirements described in this paragraph (recursively); and
• if D is a class with an implicitly-declared constructor ([class.default.ctor], [class.copy.ctor]), it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same constructor for a subobject of D.
Example
:
// translation unit 1:
struct X {
X(int, int);
X(int, int, int);
};
X::X(int, int = 0) { }
class D {
X x = 0;
};
D d1;                           // X(int, int) called by D()

// translation unit 2:
struct X {
X(int, int);
X(int, int, int);
};
X::X(int, int = 0, int = 0) { }
class D {
X x = 0;
};
D d2;                           // X(int, int, int) called by D();
// D()'s implicit definition violates the ODR

— end example
]
• if D is a class with a defaulted three-way comparison operator function ([class.spaceship]), it is as if the operator was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same comparison operators for each subobject of D.
If D is a template and is defined in more than one translation unit, then the preceding requirements shall apply both to names from the template's enclosing scope used in the template definition ([temp.nondep]), and also to dependent names at the point of instantiation ([temp.dep]).
These requirements also apply to corresponding entities defined within each definition of D (including the closure types of lambda-expressions, but excluding entities defined within default arguments or default template arguments of either D or an entity not defined within D).
For each such entity and for D itself, the behavior is as if there is a single entity with a single definition, including in the application of these requirements to other entities.
Note
:
The entity is still declared in multiple translation units, and [basic.link] still applies to these declarations.
In particular, lambda-expressions appearing in the type of D may result in the different declarations having distinct types, and lambda-expressions appearing in a default argument of D may still denote different types in different translation units.
— end note
]
If the definitions of D do not satisfy these requirements, then the program is ill-formed, no diagnostic required.
Example
:
inline void f(bool cond, void (*p)()) {
if (cond) f(false, []{});
}
inline void g(bool cond, void (*p)() = []{}) {
if (cond) g(false);
}
struct X {
void h(bool cond, void (*p)() = []{}) {
if (cond) h(false);
}
};
If the definition of f appears in multiple translation units, the behavior of the program is as if there is only one definition of f.
If the definition of g appears in multiple translation units, the program is ill-formed (no diagnostic required) because each such definition uses a default argument that refers to a distinct lambda-expression closure type.
The definition of X can appear in multiple translation units of a valid program; the lambda-expressions defined within the default argument of X​::​h within the definition of X denote the same closure type in each translation unit.
— end example
]
An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.