Scope and Storage Classes
Scope और storage — दो अलग सवाल
हर variable दो सवालों का जवाब देता है:
- Scope: code में *कहाँ* इस नाम का इस्तेमाल हो सकता है?
- Storage duration (lifetime): variable *कब* बनता है और कब नष्ट होता है?
Beginners अक्सर इन्हें मिला देते हैं। जैसे function के अंदर का static variable सिर्फ उसी function में *इस्तेमाल* हो सकता है (छोटा scope), पर पूरे program के चलने तक *मौजूद* रहता है (लंबा lifetime)। Storage class specifiers — static, extern, thread_local, mutable — lifetime और linkage तय करते हैं।
Scope के प्रकार
| Scope | कहाँ declare | कहाँ दिखता है |
|---|---|---|
| Block (local) | { } के अंदर — function body, loop, if | Declaration से closing } तक |
| Function parameter | Parameter list में | पूरे function body में |
| Global (file) | सभी functions और classes के बाहर | Declaration से file के अंत तक (और extern से दूसरी files में) |
| Namespace | namespace X { } के अंदर | Namespace के अंदर, या X::name से |
| Class | Class के अंदर | Class के members में; बाहर object या Class:: से |
#include <iostream>
int total = 100; // global
int main() {
int total = 5; // local, global को छिपा देता है
{
int bonus = 2; // block scope
std::cout << total + bonus << "\n"; // 7
}
// std::cout << bonus; // error: यहाँ bonus scope में नहीं
std::cout << ::total << "\n"; // 100 — :: से global
return 0;
}जब local नाम global को छिपा दे, तो scope resolution operator ::name से global तक पहुँचते हैं। ऐसे नाम छिपाना legal है पर उलझाने वाला — अलग नाम रखना बेहतर है।
Automatic storage (default)
बिना specifier वाले local variables की storage automatic होती है: execution declaration तक पहुँचने पर बनते हैं और block ख़त्म होने पर नष्ट हो जाते हैं। हर function call को नई copies मिलती हैं। बिना initialise किए automatic variables में garbage होता है, इसलिए हमेशा initialise करें।
static local variables
static local variable एक बार initialise होता है और calls के बीच अपनी value बनाए रखता है।
#include <iostream>
void markAttendance() {
static int count = 0; // एक बार बनता है, program ख़त्म होने तक रहता है
int calls = 0; // automatic: हर call में नया
count++;
calls++;
std::cout << "count = " << count << ", calls = " << calls << "\n";
}
int main() {
markAttendance();
markAttendance();
markAttendance();
return 0;
}count अपनी value याद रखता है; calls हर बार 0 से शुरू होता है।
static globals और static class members
staticglobal variable या function सिर्फ अपनी.cppfile में दिखता है (internal linkage)। Modern C++ में anonymous namespace यही काम करता है।staticclass member हर object का नहीं, पूरी class का होता है — एक साझा copy। देखें static members।
extern: files के बीच global share करना
// config.h
extern int maxStudents; // सिर्फ declaration — अभी memory नहीं
// config.cpp
int maxStudents = 40; // एकमात्र definition
// main.cpp
#include "config.h"
#include <iostream>
int main() {
std::cout << maxStudents << "\n"; // 40
}config.h include करने वाली हर file maxStudents इस्तेमाल कर सकती है, पर define सिर्फ config.cpp करती है। Header में define करने पर "multiple definition" errors आतीं।
thread_local, mutable, register और auto
- thread_local (C++11): हर thread को variable की अपनी copy मिलती है, जो thread के रहने तक रहती है।
- mutable: data member को
constmember function के अंदर भी बदलने देता है — caches और counters के लिए। - register: कभी CPU register में रखने का सुझाव था; C++11 में deprecated और C++17 में हटा दिया गया। Compiler यह optimisation खुद करता है।
- auto: पुराने C/C++ में "automatic storage" था। C++11 से इसका मतलब है "type खुद निकालो":
auto x = 3.5;सेxdoubleबनता है।
class Report {
mutable int views = 0;
public:
void show() const { views++; /* mutable है इसलिए allowed */ }
};Storage classes की तुलना
| Specifier | Lifetime | Default value | आम इस्तेमाल |
|---|---|---|---|
| (कोई नहीं, local) | Block ख़त्म होने तक | Garbage | साधारण local variables |
static (local) | पूरा program | 0 | Counters, एक बार का setup |
global / static global | पूरा program | 0 | Program-wide settings |
extern | पूरा program (कहीं और defined) | — (declaration) | Files के बीच global share |
thread_local | Thread के रहने तक | 0 | हर thread का अलग data |
mutable | Object जितना | — | const function में member बदलना |
आम गलतियाँ
- Local (automatic) variable का pointer या reference return करना — function ख़त्म होते ही वह नष्ट हो जाता है।
- Non-static local से calls के बीच value याद रखने की उम्मीद करना।
- कई files में include होने वाले header में global को declare की जगह define कर देना।
- Global variables का ज़रूरत से ज़्यादा इस्तेमाल, जिससे programs test और debug करना मुश्किल होता है।
- Modern C++ में
register int i;लिखना — C++17 में यह error है।
nextRollNumber() function लिखें जो static local variable से हर call पर 1, 2, 3, … लौटाए। फिर उसे दो files में बाँटें और extern से global schoolCode share करें।
सारांश
- Scope = नाम कहाँ दिखता है; lifetime = variable कितनी देर मौजूद रहता है।
- Local variables automatic होते हैं: अपने block के साथ बनते और नष्ट होते हैं।
staticlocals calls के बीच value रखते हैं;staticglobals file-private होते हैं।externदूसरी file में defined global को declare करता है।registerहट चुका है;autoअब type deduction है;mutableऔरthread_localखास मामले हैं।
संबंधित: functions, static members, namespaces।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
C++ में storage classes कौन-सी हैं?
static, extern, thread_local और mutable। Function के अंदर बिना specifier वाले variables की automatic storage होती है। पुराना register specifier C++17 में हटा दिया गया, और auto अब storage class नहीं बल्कि type deduction के लिए है।Scope और lifetime में क्या अंतर है?
static local variable का scope block तक सीमित होता है (सिर्फ अपने function में इस्तेमाल), पर वह पूरे program तक जीवित रहता है।C++ में static local variable क्या करता है?
C++ में extern कब इस्तेमाल करें?
.cpp files एक ही variable share करें। Header में extern int count; और ठीक एक .cpp file में int count = 0; लिखें।