One Definition Rule
Encyclopedia
The One Definition Rule is an important concept in the C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...

 programming language
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....

. It's defined in the ISO C++ Standard(ISO/IEC 14882) 2003, at section 3.2.

Summary

In short the ODR states that:
  1. In any translation unit
    Translation unit (programming)
    In C programming language terminology, a translation unit is the ultimate input to a C compiler from which an object file gets generated.-Context:...

    , a template
    Generic programming
    In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...

    , type, function, or object
    Object (computer science)
    In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...

     can have no more than one definition. Some of these can have any number of declarations. A definition provides an instance.
  2. In the entire program
    Computer program
    A computer program is a sequence of instructions written to perform a specified task with a computer. A computer requires programs to function, typically executing the program's instructions in a central processor. The program has an executable form that the computer can use directly to execute...

    , an object or non-inline function
    Inline function
    In various versions of the C and C++ programming languages, an inline function is a function upon which the compiler has been requested to perform inline expansion...

     cannot have more than one definition; if an object or function is used, it must have exactly one definition. You can declare an object or function that is never used, in which case you don't have to provide a definition. In no event can there be more than one definition.
  3. Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same. Non-extern objects and functions in different translation units are different entities, even if their names and types are the same.


Some violations of the ODR must be diagnosed by the compiler
Compiler
A compiler is a computer program that transforms source code written in a programming language into another computer language...

. Other violations, particularly those that span translation units, are not required to be diagnosed.

Examples

In general, a translation unit shall contain no more than one definition of any class type. In this example, two definitions of the class type C occur in the same translation unit
Translation unit
In the field of translation, a translation unit is a segment of a text which the translator treats as a single cognitive unit for the purposes of establishing an equivalence...

. This typically occurs if a header file
Header file
Some programming languages use header files. These files allow programmers to separate certain elements of a program's source code into reusable files. Header files commonly contain forward declarations of classes, subroutines, variables, and other identifiers...

 is included twice by the same source file without appropriate header guards.


class C {}; // first definition of C
class C {}; // error, second definition of C


In the following, forming a pointer to S or defining a function taking a reference to S are examples of legal constructs, because they do not require the type of S to be complete. Therefore, a definition is not required.

Defining an object of type S, a function taking an argument of type S, or using S in a sizeof
Sizeof
In the programming languages C and C++, the unary operator sizeof is used to calculate the sizes of datatypes, in number of bytes. A byte in this context is the same as an unsigned char, and may be larger than the standard 8 bits, although that is uncommon in modern implementations...

 expression are examples of contexts where S must be complete, and therefore require a definition.


struct S; // declaration of S
S * p; // ok, no definition required
void f(S&); // ok, no definition required
void f(S); // ok, no definition required
S f; // ok, no definition required

S s; // error, definition required
sizeof(S); // error, definition required

More than one definition

In certain cases, there can be more than one definition of a type or a template. A program consisting of multiple header files and source files will typically have more than one definition of a type, but not more than one definition per translation unit.

If a program contains more than one definition of a type, then each definition must be equivalent.

Definitions of static const data members

In pre-standard C++, all static data members required a definition outside of their class. However, during the C++ standardization process it was decided to lift this requirement for static const integral members. The intent was to allow uses such as:

struct C {
static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition

without a namespace
Namespace (computer science)
A namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols . An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces...

 scope definition for N.

Nevertheless, the wording of the 1998 C++ standard still required a definition if the member was used in the program. This included the member appearing anywhere except as the operand to sizeof
Sizeof
In the programming languages C and C++, the unary operator sizeof is used to calculate the sizes of datatypes, in number of bytes. A byte in this context is the same as an unsigned char, and may be larger than the standard 8 bits, although that is uncommon in modern implementations...

 or typeid
Typeid
In C++, the typeid keyword is used to determine the class of an object at run time. It returns a reference to std::type_info object, which exists until the end of the program...

, effectively making the above ill-formed.

This was identified as a defect, and the wording was adjusted to allow such a member to appear anywhere a constant expression is required, without requiring an out-of-class definition. This includes array bounds, case expressions
Switch statement
In computer programming, a switch, case, select or inspect statement is a type of selection control mechanism that exists in most imperative programming languages such as Pascal, Ada, C/C++, C#, Java, and so on. It is also included in several other types of languages...

, static member initializers, and nontype template arguments
Template (programming)
Templates are a feature of the C++ programming language that allow functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one....

.


struct C {
static const int N = 10;
static const int U = N; // Legal per C++03
};

char data[C::N]; // Legal per C++03

template struct D;

template<> struct D {}; // Legal per C++03


However, using a static const integral member anywhere except where an integral constant-expression is required requires a definition:


struct C {
static const int N = 10;
};

int main {
int i = C::N; // ill-formed, definition of C::N required
}


This requirement has been relaxed in the current C++ standard, C++11.
The source of this article is wikipedia, the free encyclopedia.  The text of this article is licensed under the GFDL.
 
x
OK