A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://timsong-cpp.github.io/cppwp/n4140/basic.def.odr below:

[basic.def.odr]

3.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 (Clause [expr]) or a subexpression thereof. The set of potential results of an expression e is defined as follows:

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)            : f(S::x);                          

 — end example ]  — end note ]

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion ([conv.lval]) to x yields a constant expression ([expr.const]) 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 (Clause [expr]). this is odr-used if it 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 whose name appears as a potentially-evaluated expression is odr-used if it is the unique lookup result or the selected member of a set of overloaded functions ([basic.lookup], [over.match], [over.over]), unless it is a pure virtual function and its name is not explicitly qualified. [ Note: This covers calls to named functions ([expr.call]), operator overloading (Clause [over]), user-defined conversions ([class.conv.fct]), allocation function for placement new ([expr.new]), as well as non-default initialization ([dcl.init]). A constructor selected to copy or move an object of class type is odr-used even if the call is actually elided by the implementation ([class.copy]).  — end note ] An allocation or deallocation function for a class is odr-used by a new expression appearing in a potentially-evaluated expression as specified in [expr.new] and [class.free]. A deallocation function for a class is odr-used by a delete expression appearing in a potentially-evaluated expression as specified in [expr.delete] and [class.free]. 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]).26 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]. A default constructor for a class is odr-used by default initialization or value initialization as specified in [dcl.init]. 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 ([class.dtor]).

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; 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] and [class.copy]). An inline function shall be defined in every translation unit in which it is odr-used.

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;                       struct X* x1;                   X* x2;                          

 — 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 (Clause [class]), enumeration type ([dcl.enum]), inline function with external linkage ([dcl.fct.spec]), class template (Clause [temp]), non-static function template ([temp.fct]), static data member of a class template ([temp.static]), member function of a class template ([temp.mem.func]), 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

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. If the definitions of D do not satisfy these requirements, then the behavior is undefined.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4