Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🔵 Core C++  ·  Lesson 33

Scope and Storage Classes in C++

In this lesson: Scope and storage classes in C++ — local, global, static, extern, thread_local — with examples. In Hindi & English.

Scope and storage — two different questions

Every variable answers two questions:

  • Scope: *where* in the code can I use this name?
  • Storage duration (lifetime): *when* is the variable created and destroyed?

Beginners often mix these up. A static variable inside a function, for example, can only be *used* inside that function (small scope) but *exists* for the whole run of the program (long lifetime). Storage class specifiers — static, extern, thread_local, mutable — control lifetime and linkage.

Types of scope

ScopeDeclaredVisible
Block (local)Inside { } — function body, loop, ifFrom declaration to the closing }
Function parameterIn the parameter listWhole function body
Global (file)Outside all functions and classesFrom declaration to end of file (and other files with extern)
NamespaceInside namespace X { }Inside the namespace, or as X::name
ClassInside a classMembers of the class; outside via object or Class::
C++
#include <iostream>
int total = 100;               // global

int main() {
    int total = 5;             // local, hides the global
    {
        int bonus = 2;         // block scope
        std::cout << total + bonus << "\n";   // 7
    }
    // std::cout << bonus;     // error: bonus not in scope here
    std::cout << ::total << "\n";             // 100 — global via ::
    return 0;
}
7 100

When a local name hides a global one, the scope resolution operator ::name reaches the global. Hiding names like this is legal but confusing — better to choose different names.

Automatic storage (the default)

Local variables without a specifier have automatic storage: they are created when execution reaches the declaration and destroyed when the block ends. Each function call gets fresh copies. Uninitialised automatic variables contain garbage, so always initialise them.

static local variables

A static local variable is initialised once and keeps its value between calls.

C++
#include <iostream>

void markAttendance() {
    static int count = 0;      // created once, lives until program ends
    int calls = 0;             // automatic: recreated every call
    count++;
    calls++;
    std::cout << "count = " << count << ", calls = " << calls << "\n";
}

int main() {
    markAttendance();
    markAttendance();
    markAttendance();
    return 0;
}
count = 1, calls = 1 count = 2, calls = 1 count = 3, calls = 1

count remembers its value; calls starts at 0 every time.

static globals and static class members

  • A static global variable or function is visible only in its own .cpp file (internal linkage). In modern C++ an anonymous namespace does the same job.
  • A static class member belongs to the class, not to each object — one shared copy. See static members.

extern: sharing a global across files

C++
// config.h
extern int maxStudents;        // declaration only — no memory yet

// config.cpp
int maxStudents = 40;          // the one definition

// main.cpp
#include "config.h"
#include <iostream>
int main() {
    std::cout << maxStudents << "\n";   // 40
}

Every file that includes config.h can use maxStudents, but only config.cpp defines it. Defining it in the header instead would cause "multiple definition" errors.

thread_local, mutable, register and auto

  • thread_local (C++11): each thread gets its own copy of the variable, living as long as the thread.
  • mutable: lets a data member be changed even inside a const member function — used for caches and counters.
  • register: once a hint to keep a variable in a CPU register; deprecated in C++11 and removed in C++17. Compilers optimise this themselves.
  • auto: in old C/C++ meant "automatic storage". Since C++11 it means "deduce the type": auto x = 3.5; makes x a double.
C++
class Report {
    mutable int views = 0;
public:
    void show() const { views++; /* allowed because mutable */ }
};

Storage classes compared

SpecifierLifetimeDefault valueTypical use
(none, local)Until block endsGarbageOrdinary local variables
static (local)Whole program0Counters, one-time setup
global / static globalWhole program0Program-wide settings
externWhole program (defined elsewhere)— (declaration)Share a global across files
thread_localLife of the thread0Per-thread data
mutableSame as the object—Change a member in a const function

Common mistakes

  • Returning a pointer or reference to a local (automatic) variable — it is destroyed when the function ends.
  • Expecting a non-static local to remember its value between calls.
  • Defining (not just declaring) a global in a header included by many files.
  • Overusing global variables, which makes programs hard to test and debug.
  • Writing register int i; in modern C++ — it is an error in C++17.
🏋️ Practice

Write a function nextRollNumber() that returns 1, 2, 3, … on successive calls using a static local variable. Then split it into two files and share a global schoolCode using extern.

Summary

  • Scope = where a name is visible; lifetime = how long the variable exists.
  • Local variables are automatic: created and destroyed with their block.
  • static locals keep their value between calls; static globals are file-private.
  • extern declares a global defined in another file.
  • register is gone; auto now means type deduction; mutable and thread_local are special cases.

Related: functions, static members, namespaces.

Frequently Asked Questions

What are the storage classes in C++?
Modern C++ has the storage class specifiers static, extern, thread_local and mutable. Variables without a specifier inside a function have automatic storage. The old register specifier was removed in C++17, and auto now means type deduction rather than a storage class.
What is the difference between scope and lifetime?
Scope is where in the code a name can be used; lifetime is how long the variable actually exists in memory while the program runs. A static local variable has block scope (usable only inside its function) but lives for the whole program.
What does a static local variable do in C++?
A static local variable is created and initialised only once, the first time control reaches its declaration, and it keeps its value between function calls. It is often used for counters, such as counting how many times a function has been called.
When should I use extern in C++?
Use extern to declare a global variable that is defined in another source file, so several .cpp files can share one variable. Write extern int count; in a header and int count = 0; in exactly one .cpp file.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicPreprocessor Directives Your progress: 33 / 81 (41%) · Lesson 34 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free