6 Basics [basic]

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

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
An expression is potentially evaluated unless it is an unevaluated operand or a subexpression thereof.
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, the set contains the potential results of the object expression.
  • If e is a pointer-to-member expression whose second operand is a constant expression, the set contains the potential results of the object expression.
  • 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 as follows:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion ([conv.lval]) is applied to e, or e is a discarded-value expression ([expr.prop]).
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.
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]).22
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:
  • the local entity is either 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
  [&] { [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.ctor], [class.dtor], [class.copy.ctor], and [class.copy.assign]).
An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
Exactly one definition of a class is required in a translation unit if 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 class type, enumeration type, inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template, non-static function template, concept ([temp.concept]), static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
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 [basic.lookup], shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution 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, 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, 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 requirements described in this paragraph (and, if the default argument has subexpressions with default arguments, this requirement applies recursively)23; and
  • if D invokes a function with a precondition, or is a function that contains an assertion or has a contract condition ([dcl.attr.contract]), it is implementation-defined under which conditions all definitions of D shall be translated using the same build level and violation continuation mode; and
  • if D is a class with an implicitly-declared constructor, 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 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]).
If the definitions of D satisfy all these requirements, then the behavior is as if there were a single definition of D.
[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.
end note
]
If the definitions of D do not satisfy these requirements, then the behavior is undefined.
An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.
[dcl.fct.default] describes how default argument names are looked up.