Skip to content

Beginner · Functions and arrays · topic 12 of 60 · 25 min

Scope and storage classes

Explanation

Scope is where a name can be used; lifetime is how long the variable exists. Local (automatic) variables live inside a block for one call. Global variables live for the whole program. A static local variable keeps its value between calls, static on a global variable or function makes it private to its file, and extern declares a global defined in another file.

Local variables

A variable declared inside a function or block is local: it can be used only inside that block (its scope), and it exists only while the block runs (automatic lifetime). Each call gets fresh local variables. Locals are not initialised automatically, so always give them a value.

c
void count_calls(void) {
    int calls = 0;        /* a new variable every call */
    calls++;
    printf("%d\n", calls);   /* always prints 1 */
}

static local variables

c
void count_calls(void) {
    static int calls = 0;    /* created once, keeps its value between calls */
    calls++;
    printf("%d\n", calls);   /* 1, then 2, then 3 … */
}
A static local is initialised once (to 0 if you give no value) and lives for the whole program, but its NAME is still visible only inside the function.

Global variables

c
int total_orders = 0;          /* global: visible from here to the end of the file, lives forever */

void place_order(void) { total_orders++; }

Globals are automatically initialised to 0. They are easy to use but hard to reason about: any function can change them, which makes bugs and testing harder, and they are unsafe with threads. Prefer passing values as parameters and returning results.

Shadowing

c
int rate = 18;                 /* global */
void show(void) {
    int rate = 5;              /* local shadows the global inside this function */
    printf("%d\n", rate);      /* 5 */
}
gcc -Wshadow warns about this; it is a common source of confusion.

static and extern for files

Big programs are split into several .c files (module 8). static before a global variable or a function makes it private to its file (internal linkage), so other files cannot see or clash with it. extern declares a global that is defined in another file, so this file can use it.

c
/* tax.c */
int gst_rate = 18;                     /* defined here, visible to other files */
static double round2(double x) { … }   /* private helper, only tax.c can call it */

/* main.c */
extern int gst_rate;                   /* declared: "it exists in another file" */
DeclarationScope (where the name works)Lifetime
int x; inside a functionThat blockOne call (automatic)
static int x; inside a functionThat blockWhole program
int x; outside functionsThe file (and other files via extern)Whole program
static int x; outside functionsThis file onlyWhole program
Careful: Never return the address of a local (automatic) variable from a function: the variable is destroyed when the function returns, so the pointer points to dead memory (a dangling pointer, module 5). Returning a value is fine; returning &local is a bug.
Think of it like this: A local variable is like a whiteboard in a meeting room that is wiped after every meeting. A static local is a notebook kept in that room: still private to the room, but the notes survive between meetings. A global is the notice board in the corridor that anyone can scribble on.
Tip: Make every function and global that is not used by other files static. It documents intent, prevents name clashes and helps the compiler optimise.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Scope and storage classes · 1/6

Scope and storage

In this lesson you will learn where variables can be used and how long they live.

Prefer a video by a teacher? Find free videos on “c storage classes static extern auto scope lifetime” on YouTube ↗

In real life: Generating receipt numbers

A shop's billing module numbers receipts with a static counter inside next_receipt_no(). No other part of the program can change the counter by mistake, and it keeps counting across calls.

c
int next_receipt_no(void) {
    static int last = 1000;
    return ++last;          /* 1001, 1002, 1003 … */
}

Practice (0/3 done)

Task 1 · Question

What does this print? void f(void) { static int n = 0; int m = 0; n++; m++; printf("%d%d ", n, m); } … f(); f(); f();

Task 2 · Question

What does static do on a function defined at file level?

Task 3 · Practice

Write a function int next_token(void) that returns 1, 2, 3, … on successive calls using a static local, and a function void reset_hint(void) explaining in a comment why it cannot reset that counter. Then rewrite it with a file-level static variable and a reset function, and say which design you prefer and why.

Quick quiz

Question 1

1.What is the initial value of a global int with no initialiser?

Question 2

2.What does extern int count; mean?

Question 3

3.A local variable with the same name as a global…

Question 4

4.How long does a static local variable live?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is the initial value of a global int with no initialiser?

Answer: 0

Objects with static storage duration are zero-initialised.

What does extern int count; mean?

Answer: count is defined somewhere else (another file)

A declaration, not a definition.

A local variable with the same name as a global…

Answer: Shadows the global inside its block

Inside the block, the local wins.

How long does a static local variable live?

Answer: The whole program run

Static storage duration.

Where do uninitialised global variables live?Related

Answer: .bss (zero-initialised)

They start as zero.

From Stack and heap

What does extern int count; in a header mean?Related

Answer: count is defined in some .c file; this just declares it

A declaration without storage.

From Splitting a program into files

A variable is created inside a function. Where can you use it?Related

Answer: Only inside that function

Variables made inside a function are local to it and disappear when the function ends.

From Scope: where variables live

The compiler suggests adding 'static to a returned reference to a local String. What is usually the right fix?Related

Answer: Return the owned String instead

A local String is dropped at the end of the function; returning ownership is the clean fix.

From Lifetimes

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Functions and arrays” before its exam: Recursion, Arrays, 2D arrays and classic array algorithms.
  2. Module 3 exam: Functions and arrays · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Strings in C. 60 topics left in the course before the final exam.

← Previous: Functions