C++: Scope and Lifetime
Last updated: 2026-08-26
Variables are not "accessible everywhere once defined."
Some variables can only be used within a pair of braces, some can be used in all functions, and others can still "remember" their previous value after a function ends.
This is scope and lifetime.
1. Scope
Scope is the range where a variable can be accessed.
(1) 1.1 Three Types of Scope
| Scope Type | Declaration Location | Accessible Range |
|---|---|---|
| Local scope | Inside a function | From declaration to end of function |
| Global scope | Outside all functions | From declaration to end of file (other files can access with extern) |
| Block scope | Inside a statement block (e.g., if, for) |
From declaration to end of block |
▶ Example 1: Local Variables vs Global Variables (Difficulty ⭐)
#include <iostream>
int gGlobalVar = 100; // Global variable
void foo() {
int localVar = 5; // Local variable
std::cout << "foo: localVar = " << localVar << std::endl;
std::cout << "foo: gGlobalVar = " << gGlobalVar << std::endl;
}
int main() {
foo();
// std::cout << localVar << std::endl; // ❌ Error: localVar declared in foo, not visible in main
std::cout << "main: gGlobalVar = " << gGlobalVar << std::endl; // ✅ Global variable accessible everywhere
return 0;
}
Output:
foo: localVar = 5
foo: gGlobalVar = 100
main: gGlobalVar = 100
💡 Key point: When a local variable and a global variable have the same name, the local variable takes precedence (proximity rule).
#include <iostream>
int x = 100; // Global variable
int main() {
int x = 5; // Local variable (same name as global variable)
std::cout << "x = " << x << std::endl; // Output 5 (local variable takes priority)
std::cout << "::x = " << ::x << std::endl; // Output 100 (use :: to access global variable)
return 0;
}
2. Block Scope
Variables declared inside statement blocks like if, for, while can only be used within the block.
#include <iostream>
int main() {
if (true) {
int blockVar = 5; // Block scope
std::cout << "Inside block: blockVar = " << blockVar << std::endl;
}
// std::cout << blockVar << std::endl; // ❌ Error: blockVar does not exist outside block
return 0;
}
💡 Tip: The loop variable of a for loop (e.g., int i = 0) also has block scope. Since C++11, it's recommended to declare loop variables inside the for statement so their scope is limited to the loop.
3. Lifetime
Lifetime is the duration from when a variable is "born" to when it "dies."
| Storage Category | Lifetime | Scope | Keyword |
|---|---|---|---|
| Automatic variable | Born when function is called, dies when function ends | Local | (default) |
| Static local variable | Born when program starts, dies when program ends | Local | static |
| Global variable | Born when program starts, dies when program ends | Global | (default) |
| Static global variable | Born when program starts, dies when program ends | File scope | static |
(1) 3.1 Automatic Variables (Default)
#include <iostream>
void foo() {
int x = 5; // Automatic variable (default)
std::cout << "x = " << x << std::endl;
x++; // Modify x
std::cout << "x = " << x << std::endl;
}
int main() {
foo(); // Output:x = 5, x = 6
foo(); // Output:x = 5, x = 6(x recreated)
return 0;
}
💡 Key point: Automatic variables are created when a function is called and destroyed when the function ends. When the function is called again, the variable is recreated (its value is not preserved).
(2) 3.2 Static Local Variables (static)
#include <iostream>
void foo() {
static int x = 5; // Static local variable (initialized only once)
std::cout << "x = " << x << std::endl;
x++; // Modify x
}
int main() {
foo(); // Output:x = 5
foo(); // Output:x = 6(x preserved its previous value)
foo(); // Output:x = 7
return 0;
}
💡 Key point: static local variables are initialized only once, and they are not destroyed when the function ends. The next time the function is called, their value is preserved.
4. Global Variables
(1) 4.1 Basic Usage
#include <iostream>
int gCount = 0; // Global variable
void increment() {
gCount++; // Modify global variable
}
int main() {
std::cout << "Initial value: gCount = " << gCount << std::endl;
increment();
increment();
std::cout << "After two calls: gCount = " << gCount << std::endl;
return 0;
}
(2) 4.2 Pros and Cons of Global Variables
| Pros | Cons |
|---|---|
| All functions can access it | Breaks encapsulation (any function can modify it) |
| No need to pass parameters | Makes the program hard to understand (unclear who modified it) |
| Needs locking in multithreaded code (covered later) |
💡 Advice: Avoid global variables whenever possible! If multiple functions need to share data, pass it through parameters.
5. Static Global Variables
(1) 5.1 Basic Usage
// file1.cpp
static int sFileVar = 5; // Static global variable (only accessible in file1.cpp)
// file2.cpp
extern int sFileVar; // ❌ Error: file2.cpp cannot see sFileVar
💡 Key point: static global variables can only be used in the current file — other files cannot access them via extern. This helps avoid naming conflicts.
6. Practice: Counter Function
▶ Example 2: Implementing a Counter with Static Local Variables (Difficulty ⭐⭐)
#include <iostream>
int getCount() {
static int count = 0; // Static local variable
count++;
return count;
}
int main() {
std::cout << "No. " << getCount() << " time call" << std::endl;
std::cout << "No. " << getCount() << " time call" << std::endl;
std::cout << "No. " << getCount() << " time call" << std::endl;
return 0;
}
Output:
No. 1 time call
No. 2 time call
No. 3 time call
💡 Tip: This technique is commonly used in "factory functions," "singleton pattern," and other scenarios (covered later).
7. Common Errors
(1) 7.1 Accessing Variables Outside Their Scope
Error example:
#include <iostream>
int main() {
if (true) {
int x = 5;
}
std::cout << x << std::endl; // ❌ Error: x does not exist outside if block
return 0;
}
Compiler error message:
error: 'x' was not declared in this scope
(2) 7.2 Forgetting to Write static
Error example:
#include <iostream>
void foo() {
int x = 0; // ❌ Forgot to write static
x++;
std::cout << "x = " << x << std::endl;
}
int main() {
foo(); // Output:x = 1
foo(); // Output:x = 1(Expected 2)
return 0;
}
▶ Example 3: Local Variables vs Block Scope Variables (Difficulty ⭐)
#include <iostream>
int globalX = 100; // Global variable
int main() {
int x = 10; // main function's local variable
{
int x = 20; // Block scope variable, shadows outer x
std::cout << "Inner block x = " << x << std::endl;
std::cout << "Global x = " << globalX << std::endl;
}
std::cout << "Outer block x = " << x << std::endl;
return 0;
}
Output:
Inner block x = 20
Global x = 100
Outer block x = 10
❓ FAQ
extern) > - Static global variables: only accessible within the current file:: scope resolution operator. > > int x = 100; // Global variable > > int main() { > int x = 5; // Local variable > std::cout << "Local x = " << x << std::endl; // 5 > std::cout << "Global x = " << ::x << std::endl; // 100 > return 0; > } >📖 Summary
- Scope is the range where a variable can be accessed (local, global, block)
- Lifetime is the duration a variable exists (automatic, static, global)
- Local variables: created when a function is called, destroyed when the function ends
- Static local variables (
static): initialized only once, value preserved after function ends - Global variables: accessible from all functions, but try to avoid using them
- Static global variables: only accessible within the current file
📝 Exercises
-
Basic (Difficulty ⭐): Write a program containing:
-
A global variable
gTotal -
A function
void addToTotal(int x)that addsxtogTotal -
In
main, calladdToTotalthree times, then outputgTotal -
Intermediate (Difficulty ⭐⭐): Write a function
int getUniqueId()that returns a unique ID each time it's called (starting from 1, incrementing by 1 each time). -
Implement it using a static local variable
-
Call it five times in
mainand output the results -
Challenge (Difficulty ⭐⭐⭐): Write a program containing the following functions:
-
void push(int x): addsxto a global array -
int pop(): removes and returns the last element from the global array -
void printStack(): prints all elements in the global array
Use a static global variable to restrict the array to the current file only (declare the array as static).
- Global variables: accessible by all functions in the file, exist from program start to end
- Local variables: visible within a block, destroyed when the block ends
- Static local variables: initialized once, only destroyed when the program ends
- Namespaces are defined with
namespaceto avoid name conflicts usingdeclarations introduce specific names;usingdirectives introduce an entire namespace
12. 🚀 Next Step
Now that you've learned scope and lifetime, let's move on to Arrays and Strings (Lesson 15) — handling multiple values of the same type, and C++ strings.