5.2.4 · D3C++ Programming

Worked examples — Namespaces — avoiding name collisions

5,159 words23 min readBack to topic

Before any example, three ideas earn their place, because the table and the examples lean on them: the name-lookup rule, what linkage means, and the One Definition Rule. We build all three now, from zero.

The name-lookup rule

When you write a bare name like f, the compiler gathers every full name that bare f could mean right now into a candidate set, then decides. The figure below draws that rule.

Figure — Namespaces — avoiding name collisions

Linkage — internal vs external

Two files (translation units) that will be linked into one program must agree on which names they share. That sharing is governed by linkage.

The One Definition Rule (ODR)

Now we clear every cell of the matrix.


The scenario matrix

Each row is a case class — a genuinely different situation the topic can throw at you. The examples afterward each fill one or more cells; nothing is left uncovered.

# Case class The dangerous input What decides the answer
C1 One clean name, qualified none — the easy case box label forces size-1 set
C2 Two libraries, same short name A::f and B::f both visible need qualification to disambiguate
C3 Zero candidates (typo / wrong prefix) name not in that box "not declared in this scope"
C4 Shadowing — a local hides a box name local abs vs std::abs leading :: / std:: to escape
C5 Nested boxes + alias very long label A::B::C::x alias makes it a size-1 shortcut
C6 Open namespace across files (ODR) same Ns::x defined in 2 .cpps linker sees 2 definitions → error
C7 Unnamed namespace (file-local) same helper name in 2 files internal linkage → no clash
C8 using namespace + overloads two dumps, then overload resolution best match wins, else ambiguous
C9 Word problem (real project) two vendor libs both ship Logger wrap each vendor in its own box
C10 Exam twist: ::swap + ADL local using vs std::swap + ADL leading :: = "start at the top"
C11 ADL corner case f(obj) finds obj's box for free argument's box joins the set
C12 Inline namespace a nested box with no label needed its names also count as the parent's

Now we clear every cell.


Example 1 — the easy case (C1)


Example 2 — two libraries, same short name (C2)


Example 3 — zero candidates: the wrong-prefix typo (C3)


Example 4 — shadowing, and escaping with :: (C4)

A local name of your own hides a box name. The figure below is the payload of this example — read it before the steps.

Figure — Namespaces — avoiding name collisions

Example 5 — nested boxes rescued by an alias (C5)


Example 6 — the open-namespace ODR trap (C6)


Example 7 — unnamed namespace makes clashes vanish (C7)


Example 8 — using namespace meets overload resolution (C8)

The figure shows two directives dumping candidates into one pool; the text then shows how overload resolution decides whether that pool is fatal.

Figure — Namespaces — avoiding name collisions

Example 9 — real-world word problem (C9)


Example 10 — the exam twist: ::swap beats a shadow, and ADL (C10, C11)


Example 11 — the inline namespace (C12)


Which cell did each example fill?

Scenario matrix C1 to C12

Ex1 fills C1

Ex2 fills C2 and C3

Ex3 fills C3

Ex4 fills C4

Ex5 fills C5

Ex6 fills C6

Ex7 fills C7

Ex8 fills C8

Ex9 fills C9

Ex10 fills C10 and C11

Ex11 fills C12

Every cell C1–C12 is covered, including the degenerate zero-candidate case (Ex3), the file-local no-clash case (Ex7), and the two corner cases reviewers love — ADL (Ex10) and inline namespaces (Ex11).


Recall Quick self-test

A bare name gives an ambiguous error. What single edit always fixes it? ::: Qualify it — write Ns::name (or ::name) to force the candidate set to size 1. Why does the same helper name in two .cpp files clash if in a named box but not in an unnamed one? ::: Named = same shared (external-linkage) full name defined twice → ODR error; unnamed = internal linkage, each file gets a hidden-unique full name → no clash. What does a leading :: (nothing before it) mean? ::: Start lookup at the global box, ignoring any local using that shadowed the name. Two functions with the same name are both visible — is that automatically ambiguous? ::: No. If they are overloads, overload resolution first tries the best match for your arguments; only an exact tie is ambiguous. How can reset(w) compile with no using and no qualifier? ::: Argument-dependent lookup (ADL) also searches the box of the argument w's type.


Connections

  • 5.2.04 Namespaces — avoiding name collisions (Hinglish)
  • One Definition Rule (ODR)
  • Linkage — internal vs external
  • Scope and Storage Duration
  • Header Files and Include Guards
  • Classes and Encapsulation
  • The Standard Library (std)