Questions tagged [one-definition-rule]

Anything related to C++ One Definition Rule (ODR), i.e. a rule of the C++ standard banning multiple definitions of most language entities. The ODR roughly mandates that most language entities (objects, functions, templates, etc.) must have a unique (non-duplicated) definition in the same translation unit or across the entire program, while multiple declarations are still possible.

The One Definition Rule (ODR) is the concept that there is at most one defined instance of a function or object allowed in a program.

In C, the One Definition Rule is described in C11 Section 6.9 in paragraph 3:

There shall be no more than one external definition for each identifier declared with internal linkage in a translation unit. Moreover, if an identifier declared with internal linkage is used in an expression (other than as a part of the operand of a sizeof or _Alignof operator whose result is an integer constant), there shall be exactly one external definition for the identifier in the translation unit.

In C++, the One Definition Rule is explained in C++11 Section 3.2 [basic.def.odr], but succinctly summarized in the first paragraph:

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

Inlined functions have their own exception clauses. Extensions to the C language relax the one definition rule strictness by permitting multiple definitions if their declarations are all compatible.

311 questions
9
votes
1 answer

C++ Modules, the Standard Library, Third-Party Libraries, and the One Definition Rule

Every year or two I decide to try out using C++ modules, but every time I run into issues, usually with the compiler. But this time my issue seems to be in the specification itself, and I can't seem to find a way around it. Consider a third-party…
sudgy
  • 491
  • 1
  • 3
  • 15
9
votes
1 answer

Is an implementation required to diagnose ODR-violations of duplicated definitions of the same explicit specialization within the same TU?

Consider a templated entity, say (A) a function template, and (B) a member enum of a class template. // (A) template int f(); // (B) template struct T { enum class E; }; Is an implementation required to diagnose ODR-violations due to…
dfrib
  • 70,367
  • 12
  • 127
  • 192
9
votes
1 answer

struct with same name but different member in C++

As per book The C++ Programming Language (Bjarne Stroustrup), in section 15.2.3 (The One definition rule) page no 425, I write program as below : file1.cpp struct S2 { int a; char b; }; file2.cpp struct S2 { int a; char bb; }; int main(){ return…
Manthan Tilva
  • 3,135
  • 2
  • 17
  • 41
8
votes
3 answers

C++: Different classes with the same name in different translation units

Consider the following example: // usedclass1.hpp #include class UsedClass { public: UsedClass() { } void doit() { std::cout << "UsedClass 1 (" << this << ") doit hit" << std::endl; } }; // usedclass2.hpp #include…
user1221434
  • 81
  • 1
  • 4
8
votes
2 answers

Inlining Template Specialization

If I have a header foo.h which I include all over my project, it seems to work fine when all it contains is: template void foo(const T param) { cout << param << endl; } But I get one definition rule (ODR) errors when I add a…
8
votes
1 answer

Safe to pass empty variables by value, when they have no definition?

If I pass an empty variable by value, even though it has no definition, is it safe and compliant? I came across this issue while working on code, overloading |, to make this print the contents of the vector v: v | print; // prints the vector v The…
Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
8
votes
1 answer

ODR violation in GCC 6.3.0 with types defined in two separate translation units

We are seeing some strange behavior in GCC with the following code example. The strange behavior is ODR violation in GCC 6.3.0 with types defined in two separate translation units. It is possibly related to recursive type definitions or incomplete…
ethortsen
  • 83
  • 4
8
votes
2 answers

I just can not understand DR 712

DR 712 was responsible for the change in the wording of [basic.def.odr]/2 in C++11 to the current wording today, in [basic.def.odr]2 and 3. But I'm still trying to understand the reason for the change, as stated in the DR, as follows: 712. Are…
João Afonso
  • 1,934
  • 13
  • 19
8
votes
5 answers

A virtual member function is used if it is not pure?

C++03 3.2.2 ...An object or non-overloaded function is used if its name appears in a potentially-evaluated expression. A virtual member function is used if it is not pure... And then later in 3.2.3 we have: Every program shall contain exactly one…
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
8
votes
1 answer

Declaring functions and variables multiple times in C++

In C++, declaring a variable multiple times shows an error during compilation. For example: int x; int x; While declaring a function multiple times doesn't show any error during compilation. For example: int add(int, int); int add(int, int); Why…
8
votes
2 answers

Assign static constexpr class member to runtime variable

I know there are a lot of similar questions, but somehow different questions. It is about the following situation: #include #include template class MyClass { public: static constexpr std::array ARRAY {{4, 3,…
marlam
  • 590
  • 5
  • 14
8
votes
4 answers

In class static const ODR

I am a bit confused by the static in-class initialization of a const member. For example, in the code below: #include struct Foo { const static int n = 42; }; // const int Foo::n; // No ODR void f(const int& param) { std::cout…
vsoftco
  • 55,410
  • 12
  • 139
  • 252
8
votes
2 answers

std::make_unique, anonymous namespace and ODR

Please consider the following testcase (reduced from LLVM source): //% cat foo1.cpp #include namespace { class A { int i; }; } class G { std::unique_ptr foo() const; }; std::unique_ptr G::foo() const { return…
octoploid
  • 625
  • 3
  • 7
8
votes
2 answers

undefined reference when accessing static constexpr float member

This code works: struct Blob { static constexpr int a = 10; }; int main() { Blob b; auto c = b.a; } But if I change int to float I get an error: struct Blob { static constexpr float a = 10.0f; }; /tmp/main-272d80.o: In function…
Anonymous Entity
  • 3,254
  • 3
  • 27
  • 41
8
votes
1 answer

pointer to function and ODR

There are so many questions on ODR but I cannot find what I'm looking for, so apologies if this a duplicate or if the title is inappropriate. Consider the following: struct t {t(*id)();}; template t type() {return {type};} This is…
iavr
  • 7,547
  • 1
  • 18
  • 53