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
13
votes
1 answer

How can __COUNTER__ cause a ODR-violation here?

In this presentation at around 00:19:00, Andrei Alexandrescu explains the implementation of his SCOPE_EXIT macro. He creates a ScopeGuard object on the stack that executes a lambda on destruction: #define ANONYMOUS_VARIABLE(str) \ …
Horstling
  • 2,131
  • 12
  • 14
13
votes
2 answers

Yet another clang/gcc discrepancy regarding ODR usage?

Why does this code compile with GCC (4.9 and 5+), but not with clang (3.5-3.9)? void test(const int&) { } int main() { const int x = 42; auto f = []{ test(x); }; } I have some vague idea that the discrepancy has to do with ODR (One Definition…
Daisy Sophia Hollman
  • 6,046
  • 6
  • 24
  • 35
13
votes
2 answers

Why does in-class initialisation of static members violate the ODR?

There are several questions on Stack Overflow along the lines of "why can't I initialise static data members in-class in C++". Most answers quote from the standard telling you what you can do; those that attempt to answer why usually point to a link…
12
votes
1 answer

Is use in an unused default member initializer still an odr-use?

Is use in a default member initializer still an odr-use, even if the default member initializer is not used by any constructor? For example, is this program ill-formed because g is odr-used and therefore its definition implicitly…
12
votes
3 answers

Why do we declare and define functions separately in C++?

I have only just started learning C++, and I see that functions are usually declared and defined separately, for example: // Declaration void sayhi(std::string name); // Definition void sayhi(std::string name) { std::cout << "Hello, " <<…
jshji
  • 196
  • 1
  • 8
12
votes
1 answer

emplace_back causes link error on static constexpr member

Why does emplace_back take a reference of the member that requires a definition? What is the difference between emplace_back(integer literal) and emplace_back(static constexpr integer member)? If I switch to C++17, it compiles fine. I found that in…
mljli
  • 593
  • 5
  • 23
11
votes
2 answers

Is it correct to say that the compiler can replace the expression `a->i` below by its value 1 because...?

The code below compiles in GCC, clang and VS2017 and the expression a->i in the return statement is replaced by its constant value 1. Is it correct to say that this is valid because a is not odr-used in the expression a->i?. struct A { static…
Ayrosa
  • 3,385
  • 1
  • 18
  • 29
11
votes
1 answer

Static constexpr odr-used or not?

How come that the following works on gcc but doesn't on clang, (see it live): constexpr int giveMeValue() { return 42; } struct TryMe { static constexpr int arr[1] = { giveMeValue() }; }; int main() { int val = TryMe::arr[0]; …
Dean
  • 6,610
  • 6
  • 40
  • 90
11
votes
3 answers

Redeclaration of global variable vs local variable

When I compile the code below #include int main() { int a; int a = 10; printf("a is %d \n",a); return 0; } I get an error: test3.c: In function ‘main’: test3.c:6:5: error: redeclaration of ‘a’ with no linkage test3.c:5:5: note:…
Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
11
votes
1 answer

Does the one-definition-rule force a single static function variable to be created?

As an example, consider this header: #include template struct A { A() { static int x; std::cout << &x << "\n"; } }; static A<> a; What if I had two different C++ files including this file - would it…
orlp
  • 112,504
  • 36
  • 218
  • 315
10
votes
1 answer

Unspecified constant expression values and ODR

Consider this program in three files: // a.h #include constexpr auto f() { int i = 0; auto l1 = [](int& j) { return ++j; }; auto l2 = [](int& j) { return j*=2; }; return l1(i) + l2(i); } template struct constant…
walnut
  • 21,629
  • 4
  • 23
  • 59
10
votes
2 answers

Why does passing to a function a set::iterator instead of a const_iterator violate the One Definition Rule?

The description of the std::set container given by cppreference.com contains this note at the end: The member types iterator and const_iterator may be aliases to the same type. Since iterator is convertible to const_iterator, const_iterator should…
10
votes
2 answers

Where should the definition of an explicit specialization of a class template be placed in C++?

According to [temp.spec]/5: For a given template and a given set of template-arguments, ... an explicit specialization shall be defined at most once in a program (according to [basic.def.odr]), and ... the definition of an explicit (full)…
xskxzr
  • 12,442
  • 12
  • 37
  • 77
10
votes
1 answer

About ODR-violations and template variables

I know that template functions don't suffer of multiple definitions when linking, like member functions defined inside a class, which are inline by default. Also, constexpr objects have internal linkage, but template variables have external linkage…
ABu
  • 10,423
  • 6
  • 52
  • 103
10
votes
1 answer

Strings in headers -- does this violate the ODR?

Consider the following program with two compilation units. // a.hpp class A { static const char * get() { return "foo"; } }; void f(); // a.cpp #include "a.hpp" #include void f() { std::cout << A::get() << std::endl; } //…
Chris Beck
  • 15,614
  • 4
  • 51
  • 87
1 2
3
20 21