Show Lecture.LocalStatic as a slide show.
CS253 Local Static
Try #1
Here’s a program to generate unique student ID numbers:
unsigned long next_id() {
unsigned long id=800000000UL;
return ++id;
}
int main() {
cout << next_id() << '\n';
cout << next_id() << '\n';
cout << next_id() << '\n';
}
800000001
800000001
800000001
That wasn’t very good.
Try #2
Let’s move id
out of next_id()
:
unsigned long id=800000000UL;
unsigned long next_id() {
return ++id;
}
int main() {
cout << next_id() << '\n';
cout << next_id() << '\n';
cout << next_id() << '\n';
}
800000001
800000002
800000003
Better, but now we have an evil global variable.
👹
Try #3
Let’s make id
static:
static unsigned long id=800000000UL;
unsigned long next_id() {
return ++id;
}
int main() {
cout << next_id() << '\n';
cout << next_id() << '\n';
cout << next_id() << '\n';
}
800000001
800000002
800000003
Better in that id
is only visible to this file,
but that’s still semi-global. Can we improve?
Try #4
Move id
back to next_id()
, but leave it static.
unsigned long next_id() {
static unsigned long id=800000000UL;
return ++id;
}
int main() {
cout << next_id() << '\n';
cout << next_id() << '\n';
cout << next_id() << '\n';
}
800000001
800000002
800000003
Hooray! Now, id
is private and persistent.
👏
Summary
- A variable has two aspects, scope and lifetime.
- scope: visibility; which code can access the variable
- lifetime: duration; when the variable is created & destroyed
- static can change either of these.
- It changes the scope of a global variable to be only the current
file.
- It changes the lifetime of a local variable so that it’s
initialized only once, and persists until program end.
Sure, it’d be better to have separate words for those distinct purposes,
but the standards committee is stingy with new words—better to re-use
old ones.
static global example
// Assume that getpid() is expensive, so do it only once.
static const pid_t pid = getpid();
int main() {
cout << pid << '\n';
cout << pid << '\n';
}
2785458
2785458
- A static global:
- is visible only in that source file (scope)
- is created at program start (lifetime)
- is destroyed at program end (lifetime).
Actually, in the global scope, const implies static,
so the above definition is a bit redundant.
static local example
string homedir() {
// Assume that getpwuid() is expensive--do it only once.
// Segfault if the lookup fails! ☹
static string dir = getpwuid(getuid())->pw_dir;
return dir;
}
int main() {
cout << homedir() << '\n';
cout << homedir() << '\n';
}
/s/bach/a/class/cs253
/s/bach/a/class/cs253
- A static local:
- is visible only in that function (scope)
- is created upon first use—when the function
is first called (lifetime)
- is destroyed at program end (lifetime).
Example
char foo() {
static char id = 'A';
cout << "foo: returning " << id << "\n";
return id++;
}
static auto glob = foo();
int main() {
cout << "glob = " << glob << '\n';
for (int i=0; i<5; i++) {
if (i>10) {
static char zip = foo();
cout << "zip = " << zip << '\n';
}
static char bar = foo();
cout << "bar = " << bar << '\n';
}
return 0;
}
foo: returning A
glob = A
foo: returning B
bar = B
bar = B
bar = B
bar = B
bar = B