5.2.31 · D3C++ Programming

Worked examples — Inline namespaces, anonymous namespaces

3,514 words16 min readBack to topic

The scenario matrix

Think of every namespace question as a point on a grid. The two axes that matter most are:

  • Linkage axis — does a name escape its .cpp file? (This is the internal vs external linkage question.)
  • Visibility / versioning axis — from where can you write the name, and which definition wins?
Cell Scenario class Key question Example
C1 Global name in two .cpp files Does the linker collide? Ex 1
C2 Anonymous namespace in two .cpp files Same name, no collision? Ex 2
C3 Type/template in anonymous namespace Does the "not just functions" claim hold? Ex 3
C4 Anonymous namespace in a header (degenerate/wrong use) What breaks, and how much? Ex 4
C5 Inline namespace, unqualified call Which version is default? Ex 5
C6 Inline namespace, explicit v1 call (opt-out) Can old callers still pin the old code? Ex 5
C7 Moving inline to a new version (limiting case: releasing v3) One-keyword migration Ex 6
C8 [[Argument-Dependent Lookup (ADL) ADL]] through an inline namespace Is the name found unqualified?
C9 Mangled symbol / ABI (real-world link failure) Does the version bake into the symbol? Ex 8
C10 Exam twist: inline namespace vs inline function Same word, different mechanism Ex 9
C11 Inline namespace in a header across many TUs Does identical inline definition break ODR? Ex 10
Recall The two axes in one sentence

Anonymous = internal linkage (the linkage axis) ::: it decides whether a name escapes its translation unit. Inline = visibility + versioning (the lookup/ABI axis) ::: it decides which definition is the unqualified default and what the symbol is called.

The figure below draws this whole grid as a picture. Read it now: the coral boxes on the lower row are linkage-axis failures (Ex 1, and the ABI trap Ex 8); the mint / butter boxes are the "no problem, this is the fix" cells (Ex 2, Ex 3, Ex 9); the lavender boxes up the vertical axis are visibility / versioning cells (Ex 5–7). The white note in the middle is the single decision rule to memorize: ask which axis a bug lives on first. Every worked example below is one labelled box in this picture, so you can always locate where you are.

Figure — Inline namespaces, anonymous namespaces

Worked examples

Ex 1 — Global name in two files → the collision we want to avoid (cell C1)


Ex 2 — Anonymous namespace makes the collision disappear (cell C2)


Ex 3 — Anonymous namespace works for types, where static cannot (cell C3)


Ex 4 — The degenerate misuse: anonymous namespace in a header (cell C4)


Ex 5 — Inline namespace: default forward, explicit opt-out (cells C5 + C6)


Ex 6 — Limiting case: promoting a new default version (cell C7)


Ex 7 — ADL sees through an inline namespace (cell C8)

Figure — Inline namespaces, anonymous namespaces

Ex 8 — Real-world ABI trap: version baked into the mangled symbol (cell C9)


Ex 9 — Exam twist: inline function vs inline namespace (cell C10)


Ex 10 — Edge case: an inline namespace in a header, included by many TUs (cell C11)



Recall