Background:
The scope of variables is a fundamental concept since the emergence of programming languages. In C++, the rules of scope have significantly evolved with the introduction of new standards (from local declarations to anonymous namespaces, lambda expressions, and try/catch blocks).
Problem:
A misunderstanding of variable scope can lead to compile-time or runtime errors, for example, name collisions, unintentional variable hiding, memory leaks, and uninitialized values.
Solution:
In C++, the main levels of scope are:
It is crucial to remember the rules of name lookup: the compiler searches for the "closest" definition and then goes up the scope chain.
Code example:
#include <iostream> void func() { int x = 1; { int x = 2; // hiding the outer variable x std::cout << x << '\n'; // Will output: 2 } std::cout << x << '\n'; // Will output: 1 } int x = 10; // global variable int main() { func(); std::cout << x << '\n'; // Will output: 10 }
Key features:
Can a variable declared in a header file outside any function cause a link-time error?
Yes! If the variable is declared as just int value (without extern and without inline initialization with inline variables in C++17), it will create multiple definitions and lead to a multiple definition error at the linking stage.
Code example:
// myheader.h int globalVar = 5; // BAD: definition, not declaration
What happens if a variable with the same name is declared inside an inner block?
The inner variable will "hide" the outer one, and all references will go to it until the inner block ends.
Is a variable declared in a function header available in other functions?
No. Variables declared (and defined) within the function body exist only during the execution of that function. They are not accessible outside it.
In a project, a global variable is used to store state and is defined in multiple source files through header inclusion.
Pros: Easy access from anywhere.
Cons: Trouble debugging, multiple definitions (linker error), lack of thread safety, unexpected values.
Using local variables, passing state through function parameters, with little to no global variables or using extern only with encapsulation through namespaces.
Pros: Code transparency, dependency management, simplicity in testing.
Cons: Sometimes requires more code than with global variables.