Scope
Each declaration that appears in a C++ program is only visible in some possibly discontiguous scopes .
Within a scope, unqualified name lookup can be used to associate a name with its declaration.
General
Each program has a global scope , which contains the entire program.
Every other scope S is introduced by one of the following:
- a declaration
- a parameter in parameter list
- a statement
- a handler
| (since C++26) |
S always appear in another scope, which thereby contains S.
An enclosing scope at a program point is any scope that contains it; the smallest such scope is said to be the immediate scope at that point.
A scope intervenes between a program point P and a scope S (that does not contain P) if it is or contains S but does not contain P.
The parent scope of any scope S that is not a template parameter scope is the smallest scope that contains S and is not a template parameter scope.
Unless otherwise specified:
- A declaration inhabits the immediate scope at its locus.
- A declaration’s target scope is the scope it inhabits.
- Any names (re)introduced by a declaration are bound to it in its target scope.
An entity belongs to a scope S if S is the target scope of a declaration of the entity.
// global scope scope
// scope S T
int x; // ─┐ // program point X
// │
{ // │ ─┐
{ // │ │ ─┐
int y; // │ │ │ // program point Y
} // │ │ ─┘
} // ─┘ ─┘
In the program above:
- The global scope, scope
Sand scopeTcontains program pointY.
- In other words, these three scopes are all enclosing scopes at program point
Y.
- In other words, these three scopes are all enclosing scopes at program point
- The global scope contains scopes
SandT, and scopeScontains scopeT.
- Therefore, scope
Tis the smallest scope among all three, which means:
- Scope
Tis the immediate scope at program pointY. - The declaration of the variable
yinhabits scopeTat its locus. - Scope
Tis the target scope of the declaration ofy. - The variable
ybelongs to scopeT.
- Scope
- Scope
Sis the parent scope of scopeT, and the global scope is the parent scope of scopeS.
- Therefore, scope
- Scope
Sintervenes between program pointXand scopeT.
Block scope
Each
- selection statement (
if,switch), - iteration statement (
for, range-for(since C++11),while,do-while), - handler, or
- compound statement that is not the compound-statement of a handler
introduces a block scope that includes the statement or handler.
A variable that belongs to a block scope is a block variable .
int i = 42;
int a[10];
for (int i = 0; i < 10; i++) // inner “i” inhabits the block scope
a[i] = i; // introduced by the for-statement
int j = i; // j = 42
If the declaration inhabits a block scope S and declares a function or uses the extern specifier, the declaration shall not be attached to a named module (since C++20), its target scope is a larger enclosing scope (the innermost enclosing namespace scope), but the name is bound in their immediate scope S.
If a declaration that is not a name-independent declaration and(since C++26) that binds a name in the block scope S of
- the compound-statement of a function body or function
tryblock,
|
(since C++11) |
- a substatement of a selection or iteration statement that is not itself a selection or iteration statement, or
- a handler of a function
tryblock
potentially conflicts with a declaration whose target scope is the parent scope of S, the program is ill-formed.
if (int x = f()) // declares “x”
{ // the if-block is a substatement of the if-statement
int x; // error: redeclaration of “x”
}
else
{ // the else-block is also a substatement of the if-statement
int x; // error: redeclaration of “x”
}
void g(int i)
{
extern int i; // error: redeclaration of “i”
}
Function parameter scope
Each parameter declaration P introduces a function parameter scope that includes P.
- If the declared parameter is of the parameter list of a function declaration:
- If the function declaration is a function definition, the scope introduced is extended to the end of the function definition.
- Otherwise (the function declaration is a function prototype), the scope introduced is extended to the end of the function declarator.
- In both cases, the scope does not include the locus of the function declaration.
|
(since C++11) |
|
(since C++17) |
|
(since C++20) |
int f(int n) // the declaration of the parameter “n”
{ // introduces a function parameter scope
/* ... */
} // the function parameter scope ends here
Lambda scopeEach lambda expression introduces a lambda scope that starts immediately after The captures with initializers of a lambda expression auto lambda = [x = 1, y]() // this lambda expression introduces a lambda scope,
{ // it is the target scope of capture “x”
/* ... */
}; // the lambda scope ends before the semicolon
|
(since C++14) |
Namespace scope
Every namespace definition for a namespace