The Global Namespace
A name in another namespace is most simply reached by qualifying it, written as namespace_name::name, as in std::cout.
Try it: Scope: Local, Enclosing, Global, Built-in
How Python looks up a name Local → Enclosing → Global → Built-in, why assigning to a name inside a function makes it local (and raises UnboundLocalError if it is read first), and what global, nonlocal and closures change.
How it works
- Before a function runs, Python marks every name assigned inside it as local to that function, unless it is declared global or nonlocal.
- Reading a name searches the local namespace, then enclosing functions, then the module's globals, then the built-ins; the first hit wins.
- A local name read before it has a value raises UnboundLocalError (Python does not fall back to the global).
- global x makes assignments go to the module namespace; nonlocal x makes them go to the nearest enclosing function.
- A function's local frame disappears when it returns, unless an inner function (a closure) still uses its variables.
Default run (10 steps): Ready: Local shadows global. Every name is looked up Local, then Enclosing, then Global, then Built-in. … Finished. Printed: inside: 99 / outside: 10.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Built-ins shows only the names the script used.
Loading the simulation…
A Name That Lives Somewhere Else
Suppose a program has a name that belongs to one namespace, and the code that needs that name sits outside the namespace. How does the code reach the name? The question is simple to state, but the answer depends on a detail that is easy to miss: the code has to say which namespace it means, so that the name is found in the correct place and not confused with a name of the same spelling somewhere else.
What do you think happens?
Code outside a namespace needs a name that is defined inside that namespace. What information should the code give so the name is found in the right place?
Reveal answer
It should name the namespace the name belongs to, and then give the name itself. The name is reached by qualifying it with the namespace name, written as namespace_name::name.
The qualifier is what separates a name from another name with the same spelling that lives in a different namespace.
Two Names Spelled the Same
Imagine two different namespaces that each contain a name spelled count. Inside each namespace, count means something different. If the code only wrote count, the reader, and the program, would have no way to tell which one is meant. The final word is identical in both places, so the spelling alone cannot identify the name.
- Inventory is the namespace on the left of the first expression
- Sales is the namespace on the left of the second expression
- count is spelled the same in both, and the qualifier is what tells them apart
Tracing which count is meant
Two namespaces each define a name spelled count. Code outside both namespaces must use the count from Sales, not the one from Inventory. How does the code say which one it means?
- 1Identify the name that is needed
The needed name is count, but there are two names with that spelling, one per namespace.
- 2Identify the namespace that owns the wanted name
The wanted count is the one inside Sales.
- 3Attach the namespace name and the double colon
Write the namespace name, then two colons, then the name: Sales::count.
- 4Check that the expression is unambiguous
Sales::count identifies exactly one name, while the bare word count would not say which namespace it came from.
The code writes Sales::count, and the qualifier makes the reference unambiguous.
Reading a Qualified Name
The most direct way to access a name in another namespace is to qualify it with the namespace name. You write the namespace name, then two colons, then the name itself. The general form is namespace_name::name. The source gives two examples: std::cout and My_code::main. In each case the part before the double colon identifies the namespace, and the part after it identifies the name inside that namespace.
Read each expression from left to right. The left side names the container and the right side names the item inside it. The qualifier is what makes the reference unambiguous: the same final word can appear in more than one namespace, and the qualifier says which one you mean.
The Global Namespace and the Real main()
The global namespace holds names that are not local to a defined namespace, class, or function. The source makes one specific point about it: the real main() is defined there. This matters when you read a qualified name such as My_code::main. That expression refers to a name inside the My_code namespace. It is a different name from the real main(), which sits at the global level and is not local to any defined namespace. Seeing the same word in two places is exactly the situation the qualifier exists to separate.
Crossing the Namespace Boundary
Code outside a namespace reaches a name in that namespace through the boundary. The name itself does not move. It still belongs to its namespace, and the code gives a path to it. Qualification is that path, written at the point of use. Each time the code needs the name, the qualifier travels with it.
Reaching cout from outside std
Code that sits outside the std namespace wants to print through the name cout, which is defined inside std. Trace how the name is reached.
- 1Stand outside the namespace
The code is not inside std, so the bare word cout is not enough to find the name.
- 2Name the namespace
Write std, the namespace that owns cout.
- 3Add the double colon and the name
The full expression is std::cout, which the source gives as an example of qualification.
The name is found inside std through the qualified expression std::cout, and the namespace boundary is crossed without changing where cout is defined.
Using-Directives Versus Qualification
Qualifying every use of a name works, but it can become repetitive. The source introduces a second mechanism for the standard-library namespace: the using-directive. A using-directive gives you access to names in a namespace, so that you can refer to those names without writing the qualifier each time. The source presents it as the tool to reach for when you want access to names in the standard-library namespace.
Notice what the using-directive does and does not do. It changes how you are allowed to refer to names, not where those names are defined. The names still belong to their namespace. The directive is a way of reaching them more conveniently in the code that follows it.
| Feature | Qualification | Using-directive |
|---|---|---|
| What it gives you | Access to a name by naming its namespace | Access to names in a namespace without repeating the qualifier |
| Where the namespace is named | At each point of use | Once, so later code can omit it |
| Where the name is defined | Unchanged, inside its namespace | Unchanged, inside its namespace |
| Typical reading | Explicit about every source | Shorter, convenient when one namespace is used heavily |
Both techniques reach the same name; they differ in how much naming the code repeats.
Choosing Between the Two Approaches
Both techniques give you access to a name in another namespace, so the choice is about how the code reads and how clearly it identifies its sources. Qualification names the namespace at the point of use, which makes every source visible on the line where it is used. A using-directive lets you omit that naming at the point of use, which is convenient when one namespace is used heavily. Use the guiding questions below to decide.
- 1Ask whether the name is used once or only a few times in the code. A single or occasional use favours qualification, which keeps the source visible.
- 2Ask whether one namespace is used heavily throughout the code. Heavy use of one namespace favours a using-directive, which saves repeating the qualifier.
- 3Ask whether two namespaces could supply names with the same spelling. If they could, qualification protects you, because the qualifier says which one is meant.
- 4Ask whether the reader needs to see the source of each name on the line where it appears. If yes, qualify the name.
- 5Remember that a using-directive changes only how names are written, not where they are defined.
Mistakes Learners Make With Qualified Names
Common mistake Treating the qualifier as optional decoration
What it looks likeWriting cout where std::cout is needed, from code outside std
Why it failsThe bare word does not say which namespace owns the name, so the reference is ambiguous when the same spelling appears elsewhere.
Do this insteadWrite the namespace name, then the double colon, then the name: std::cout.
Common mistake Reading My_code::main as the real main()
What it looks likeAssuming My_code::main is the program entry point because it contains the word main
Why it failsThe real
main()is defined in the global namespace, not inside My_code. My_code::main is a different name inside My_code.Do this insteadRead the left side of the double colon as the container. The real main() is the global one, and My_code::main lives inside My_code.
Common mistake Believing a using-directive moves a name into another namespace
Why it failsA using-directive only changes how names are referred to in the code that follows it. The names still belong to their original namespace.
Do this insteadThink of the directive as a shorter way to reach names, not a change in where they are defined.
Common mistake Reading the expression from right to left instead of left to right, which confuses the container with the item inside it
Practice Choosing a Form
Code outside the namespace My_code needs the name main that is defined inside My_code. Another part of the same program needs the real main() that is defined in the global namespace. Write the form each part should use, and explain in one sentence why the two forms must differ.
Hints
- The qualified name has the form
namespace_name::name. - The real
main()is not local to any defined namespace, so it does not need a namespace qualifier of its own. - Compare the spelling main in both places and ask what separates them.
A file has many references to cout from code outside std, and a reader complains that the file is hard to scan. Decide whether a using-directive is appropriate here, and justify your choice using the idea that it changes only how names are written.
Hints
- Consider how heavily the std namespace is used in this file.
- Consider whether the reader still needs to see the source of each name.
Key Takeaways
- A name in another namespace is reached by qualifying it, written as
namespace_name::name, such as std::cout or My_code::main. - In a qualified name, the part before the double colon identifies the namespace and the part after it identifies the name inside that namespace.
- The global namespace holds names that are not local to a defined namespace, class, or function, and the real
main()is defined there, separate from any name like My_code::main. - A using-directive gives access to names in a namespace without repeating the qualifier, and it changes how names are written, not where they are defined.
- Qualification shows the source of each name at the point of use, while a using-directive is convenient when one namespace is used heavily.