C CLP study materials
C CLP study resources

C CLP: Functions, Scope, Storage Duration, and Linkage

C CLP · Work through your exam, one topic at a time.

All guide sections

Functions, Scope, Storage Duration, and Linkage

This domain probes three separate questions the exam likes to mix: where a name is visible (scope), how long its object lives (storage duration), and whether other translation units can see it (linkage).

Functions

  • A prototype such as int f(int, char *); gives the compiler parameter types and enables argument conversion. int f(); declares a function with unspecified parameters and disables checking; void f(void) takes no arguments.
  • Calling through a non-prototype declaration applies the default argument promotions: float becomes double, and integer types narrower than int become int.
  • main returns int; reaching its closing brace returns 0. argc counts the arguments, argv[0] is the program name, and argv[argc] is a null pointer.
  • Variadic functions use <stdarg.h>: va_list ap; va_start(ap, last); v = va_arg(ap, int); va_end(ap);. va_arg cannot verify the type you ask for.

Scope, storage duration, linkage

  • Scopes: block, function (labels), function prototype, and file.
  • Storage durations: automatic (ordinary block variables), static (file-scope objects and static locals, zero-initialized, alive for the whole program), thread (_Thread_local), and allocated (malloc).
  • Linkage: static at file scope gives internal linkage; a plain definition gives external linkage; a block-scope extern declaration refers to a definition elsewhere.
  • A static local keeps its value between calls and is initialized once, with a constant expression, before main runs.

Worked example

static int next_id(void) {
    static int id = 0;
    return ++id;
}

id has static storage duration and no linkage; its initializer runs once, so three calls return 1, 2, 3. next_id has internal linkage, so a second translation unit that declares int next_id(void); and calls it either fails to link or binds to a different function - the declaration does not make this definition visible.

Traps

  • Initializing a static local with a runtime value (static int x = f();) is invalid in C.
  • Returning the address of an automatic variable yields a dangling pointer.
  • Defining a non-inline, non-static function in a header causes multiple-definition link errors; static inline gives one copy per translation unit.
  • File-scope const does not give internal linkage in C, unlike C++.
  • An extern declaration that carries an initializer is a definition.