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
8
votes
3 answers

constexpr and ODR

If we have a header file widget.hpp with the contents below: constexpr int foo = 10; struct widget { int bars[foo]; }; ...and we have two translation units generated from two source files which both only include widget.hpp, does this violate…
Simple
  • 13,992
  • 2
  • 47
  • 47
8
votes
2 answers

What am I allowed to do with a static, constexpr, in-class initialized data member?

This is probably a bit of an unusual question, in that it asks for a fuller explanation of a short answer given to another question and of some aspects of the C++11 Standard related to it. For ease of reference, I shall sum up the referenced…
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
7
votes
2 answers

Does the standard allow an implicit virtual destructor not being implicitly defined when no instances of its class are created?

While thinking about this question, I stumbled upon something else I don't understand. Standard says... [class.dtor]/4 If a class has no user-declared destructor, a destructor is implicitly declared as defaulted. An implicitly-declared destructor…
7
votes
3 answers

inline function in different translation units with different compiler flags undefined behaviour?

in visual studio you can set different compiler options for individual cpp files. for example: under "code generation" we can enable basic runtime checks in debug mode. or we can change the floating point model (precise/strict/fast). these are just…
7
votes
1 answer

Do C++ modules make ODR violations absent?

From the N4720 C++ Modules draft, [basic.def.odr]/6 says: […] For an entity with an exported declaration, there shall be only one definition of that entity; a diagnostic is required only if the abstract semantics graph of the module contains a…
Mário Feroldi
  • 3,463
  • 2
  • 24
  • 49
7
votes
2 answers

c++ include different header files with same implementation of class in multiple source files

For example a.h class Dummy { public: Dummy() { std::cout << "a.h" << std::endl; } }; b.h class Dummy { public: Dummy() { std::cout << "b.h" << std::endl; } }; c.cc #include "a.h" void test() { Dummy a; } d.cc #include "b.h" int main() { …
Scy
  • 488
  • 3
  • 11
7
votes
1 answer

Dependent Expression and ODR-use in a Generic Lambda in C++14

void f( int , const int (&)[2] = {}) { } // #1 void f( int , const int (&)[1] ) { } // #2 // void f(const int&, const int (&)[1] ) { } // #2_original void test() { const int x = 17; auto g = [](auto a) { …
José Luis
  • 397
  • 1
  • 11
7
votes
1 answer

Does the following actually violate the ODR?

From here: struct piecewise_construct_t {}; constexpr piecewise_construct_t piecewise_construct = {}; const int magic_number = 42; inline std::tuple make_magic() { return std::tuple( piecewise_construct, magic_number ); } This function…
JustinBlaber
  • 4,629
  • 2
  • 36
  • 57
7
votes
2 answers

How would use of unnamed namespaces in headers cause ODR-violations?

In the Google C++ Style Guide, the Namespaces section states that "Use of unnamed namespaces in header files can easily cause violations of the C++ One Definition Rule (ODR)." I understand why not using unnamed namespaces in an implementation file…
boycy
  • 1,473
  • 12
  • 25
7
votes
2 answers

explicit specialization of class method - symbol already defined

The One Definition Rule states that a program should contain one definition of every non-inline function. For members of template classes, this not entirely clear to me: /////////// // Tfoo.h template class A { void foo(){} …
xtofl
  • 40,723
  • 12
  • 105
  • 192
6
votes
1 answer

Does a range based for loop over an array ODR-use the array?

When a range based for loop is used to iterate over an array, without binding a reference to each element, does this constitute an ODR-use of the array? Example: struct foo { static constexpr int xs[] = { 1, 2, 3 }; }; int test(void) { int…
TrentP
  • 4,240
  • 24
  • 35
6
votes
2 answers

Can ODR violation be avoided by using hidden visibility?

So for example, I have a slightly complicated case of library dependency in one of my projects: /--------------------------------\ | | /----> GRPC <------------------\ | …
6
votes
1 answer

Is taking the address of an undefined function allowed?

The following code defines the entire program. Is this program standard conformant (with the latest version)? void foo(); int main() { auto x = &foo; return 0; } Here is a convenience shortcut. This code has no practical use, I'm just…
Timo
  • 9,269
  • 2
  • 28
  • 58
6
votes
6 answers

Why does the one definition rule exist in C/C++

In C and C++, you can't have a function with two definitions. For example, say we have the following two files: 1.c: int main(){ return 0;} 2.c: int main(){ return 0;} Issuing the command gcc 1.c 2.c will give you a duplicate symbol linker…
user12848549
6
votes
1 answer

ASAN detects ODR violation of vtable of class which is shared with dynamically loaded library

I'm working on a project which has a "util" library containing stuff like logging, assertion handling etc. This is compiled into a static library with -fPIC added. I also have a plugin system, where the plugins are shared libraries loaded at runtime…
Flamefire
  • 5,313
  • 3
  • 35
  • 70