Namespaces
Variants

Scope

From cppreference.com
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

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:

(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 S and scope T contains program point Y.
  • In other words, these three scopes are all enclosing scopes at program point Y.
  • The global scope contains scopes S and T, and scope S contains scope T.
  • Therefore, scope T is the smallest scope among all three, which means:
  • Scope T is the immediate scope at program point Y.
  • The declaration of the variable y inhabits scope T at its locus.
  • Scope T is the target scope of the declaration of y.
  • The variable y belongs to scope T.
  • Scope S is the parent scope of scope T, and the global scope is the parent scope of scope S.
  • Scope S intervenes between program point X and scope T.

Block scope

Each

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

(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 try block

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 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.
  • If the declared parameter is of the parameter list of a lambda expression, the scope introduced is extended to the end of { body }.
(since C++11)
  • If the declared parameter is of the parameter list of a deduction guide, the scope introduced is extended to the end of that deduction guide.
(since C++17)
  • If the declared parameter is of the parameter list of a requires expression, the scope introduced is extended to the end of { requirement-seq }.
(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 scope

Each lambda expression introduces a lambda scope that starts immediately after [captures ] and extends to the end of { body }.

The captures with initializers of a lambda expression E inhabit the lambda scope introduced by E.

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