5.2.4 · D5C++ Programming

Question bank — Namespaces — avoiding name collisions

1,599 words7 min readBack to topic

True or false — justify

True or false: two functions named f in different namespaces will collide at link time.
False. Their full names differ (A::f vs B::f), so the linker sees two distinct entities — different prefix means no collision.
True or false: wrapping code in namespace App { ... } makes those names private.
False. Namespaces only rename; every member stays reachable from anywhere via App::member. Privacy comes from class `private:` or unnamed namespaces, not namespaces in general.
True or false: using namespace std; inside one function body pollutes the whole program.
False. A using-directive obeys scope — it only affects the enclosing block, so it dies at the closing }. The real danger is putting it in a header, which leaks into every includer.
True or false: you may define Ns::x (a variable, defined identically) in two different .cpp files because they share the same namespace.
False. A namespace is open and spans files, so both are the one entity Ns::x — two definitions violate the ODR and the linker rejects it. Declare extern in a header, define once.
True or false: a namespace alias creates a copy of the namespace.
False. namespace CPN = Company::Project::Net; makes a local synonym — a second name pointing at the same box. Changing the alias redirects references but copies nothing.
True or false: the global scope is itself a namespace.
True. The global scope is the unnamed top-level namespace, reachable with a leading ::name. That is why ::swap means "the global-scope swap."
True or false: an unnamed namespace and file-scope static give the same visibility.
True in effect — both give internal linkage, so the name is private to its TU. The unnamed namespace is the modern preferred form and also works for types, which static cannot express.
True or false: using std::cout; brings in all of std.
False. That is a using-declaration — it introduces exactly one name, cout. The using-directive using namespace std; is the one that dumps everything.
True or false: you can add your own function to the std namespace.
False (with rare exceptions like specializing certain templates). Adding names to std is undefined behaviour; keep your names in your own namespace instead.

Spot the error

namespace A { void f() {} }
namespace B { void f() {} }
using namespace A;
using namespace B;
int main() { f(); }
``` — what breaks and why? ::: The call `f()` is **ambiguous**: both using-directives put `A::f` and `B::f` into lookup with equal rank, so the compiler cannot choose. Fix by qualifying: `A::f();`.
 
```cpp
// in header "log.h"
using namespace std;
``` — why is this a defect even though it compiles? ::: Every file that `#include`s `log.h` silently inherits *all* of `std` into its scope, so a user's `distance` or `count` can suddenly clash with `std::distance`. Never place a using-directive in a [[Header Files and Include Guards|header]].
 
```cpp
namespace Ns { int x = 1; }   // in a.cpp
namespace Ns { int x = 2; }   // in b.cpp
``` — what does the linker say? ::: An ODR / "multiple definition of `Ns::x`" error. Both refer to the single entity `Ns::x`; a definition may appear only once across the program.
 
```cpp
using std::swap;
swap(a, b);   // wanted the global one
``` — how do you force the global `swap`? ::: Write `::swap(a, b)`. A leading `::` restarts lookup at the top-level global namespace, bypassing the `using`-introduced `std::swap`.
 
```cpp
namespace Company { namespace Project { int port; } }
int p = Project::port;
``` — why won't this compile? ::: `Project` is not a top-level name; its full name is `Company::Project`. You must write `Company::Project::port` (or make an alias).
 
```cpp
namespace {
    int helper() { return 7; }
}
// then in another .cpp file:
extern int helper();   // trying to reuse it
``` — why does the link fail? ::: The unnamed-namespace `helper` has internal linkage, so it is invisible outside its own TU. The other file's `extern` declaration finds no matching external symbol.
 
---
 
## Why questions
 
Why does `Foo::bar` never trigger a lookup search through enclosing scopes? ::: The qualification forces the candidate set to exactly `{Foo::bar}` — there is nothing to search. Unqualified `bar` is what triggers the scope-by-scope search that can end in ambiguity.
 
Why is a using-directive riskier than a using-declaration? ::: A using-declaration names one identifier you consciously chose; a using-directive imports *every* name from the namespace, so future additions to that namespace (or to [[The Standard Library (std)|std]]) can start clashing with your code without you touching a thing.
 
Why do library authors wrap their public API in a namespace at all? ::: So users can keep their own short names (like a variable `parse`) without coordinating with the librarydifferent prefixes give different full names, letting both coexist. It removes the need for global name coordination "with everyone on Earth."
 
Why does a namespace alias make code more readable without sacrificing uniqueness? ::: The long prefix `Company::Project::Net` is unique but unreadable; the alias `CPN` is a short *local* synonym that still resolves to that exact unique box — you keep uniqueness and gain brevity.
 
Why can the same name exist as `std::count` and `App::count` at once, but not as two `count`s in the global scope? ::: The two namespaced versions have distinct full names, so lookup can always tell them apart. Two global `count`s share one full name (`::count`) — that is a genuine collision / redefinition.
 
Why is putting helpers in an unnamed namespace better than making them global? ::: File-local helpers with the same name in different `.cpp` files would otherwise collide at link time; internal linkage confines each to its own TU, eliminating cross-file clashes entirely.
 
---
 
## Edge cases
 
What is the full name of a name defined in the global scope, and how do you write it explicitly? ::: Its "prefix" is empty (the unnamed top-level namespace), and you write it explicitly as `::name` with nothing before the `::`.
 
If a namespace is *reopened* in a third file to add a new function, is that legal? ::: Yesnamespaces are open, so adding *new distinct* members across files is fine. Only re-*defining the same* member is the ODR problem.
 
What happens if two using-directives import the same name but that name is never actually called? ::: Nothing. Ambiguity is only diagnosed at the *point of use*; merely making two `f`s visible is legal until you write an unqualified `f()`.
 
Can an unnamed namespace contain a *type* (a class), and does that class have internal linkage? ::: Yestypes are allowed, and the type is confined to the TU. This is one thing file-scope `static` could never do, which is why unnamed namespaces replaced it.
 
If a local `using std::cout;` and a global variable `cout` both exist, which does an unqualified `cout` pick inside that block? ::: Lookup finds the nearer, block-scope `using`-introduced `std::cout` first, shadowing the global; write `::cout` to reach the global one deliberately.
 
Does `namespace Company::Project::Net { ... }` (C++17 nesting) create three new namespaces or reopen existing ones? ::: It opens (creating if absent, reopening if present) each level in turn — it is pure shorthand for the three separate nested `namespace` blocks, with identical meaning.
 
Is `A::f()` still unambiguous if *only* `using namespace A;` is active (no `B`)? ::: Yes, and even the unqualified `f()` would be fine then — ambiguity needs two equally-ranked candidates. One visible `f` resolves cleanly.
 
---
 
> [!mnemonic] The trap-spotter's checklist
> **"Prefix, Open, Not-private, Header-danger."**
> - **Prefix** → different box ⇒ different full name ⇒ no collision.
> - **Open** → same `Ns::x` in two files ⇒ ODR error.
> - **Not-private** → namespaces rename, they don't hide.
> - **Header-danger** → never `using namespace` in a header.
 
---
 
## Connections
- [[Namespacesavoiding name collisions]]
- [[One Definition Rule (ODR)]]
- [[Linkageinternal vs external]]
- [[Scope and Storage Duration]]
- [[Header Files and Include Guards]]
- [[The Standard Library (std)]]
- [[Classes and Encapsulation]]