C Programming 3 min read

Functions, scope and storage

Each call gets a stack frame for its parameters and local variables, and C passes every argument by value, as a copy. static inside a function keeps a variable alive between calls; static at file scope hides a name from other files, and extern declares one defined elsewhere.

Left, the stack: main's frame holds value, and try_change's frame holds x, a copy of value; the frame is gone when the function returns. Right, static storage: calls and next_id's id exist for the whole run of the program.
Locals live in a stack frame for one call; static variables live for the whole program.

Calls and the stack

When a function is called, it gets a stack frame: room for its parameters, its local variables and the return address. The frame disappears when the function returns, so a local variable lives only for one call. Arguments are copied into the frame: changing a parameter inside a function changes the copy, never the caller's variable. To let a function change the caller's data, pass a pointer to it.

storage.cC
#include <stdio.h>static int calls;               /* file scope, private to this file, starts at 0 */static int next_id(void) {    static int id = 100;        /* set once, kept between calls */    calls++;    return id++;}static void try_change(int x) {    x = 99;                     /* changes the copy only */    printf("inside: x = %d\n", x);}int main(void) {    int value = 5;              /* automatic: lives in main's stack frame */    try_change(value);    printf("value = %d\n", value);    printf("id %d\n", next_id());    printf("id %d\n", next_id());    printf("calls = %d\n", calls);    return 0;}
Output
inside: x = 99
value = 5
id 100
id 101
calls = 2

static and extern

static means two things. Inside a function, a static variable is created once, before the program starts, and keeps its value between calls: id above continues from 100. At file scope, static limits a name to its own .c file, which keeps module internals private and avoids name clashes when files are linked. extern int count; declares a variable that another file defines; it reserves no storage.