C/C++ Arena

Step 3 of 7

extern and shared state

A global variable defined in one file can be used from other files. The file that uses it needs a declaration saying "this variable exists, with this type, defined somewhere else". That's what extern is for:

/* config.h: the declaration, included wherever it's used */
extern int max_rounds;

/* config.c: the one definition, which actually creates the variable */
int max_rounds = 30;

Declaration vs definition

This distinction runs through all of C:

For functions, a prototype is a declaration and is implicitly extern. For variables, extern int x; is a declaration, while int x = 5; at file scope is a definition.

#include <stdio.h>

extern const char *app_name;
extern int version;

int main(void) {
    printf("%s v%d\n", app_name, version);
    return 0;
}

const char *app_name = "arena";
int version = 3;
arena v3

Here the declarations come first, so main can use the variables that are defined further down. In a real project the definitions would be in another file.

A warning about globals

Mutable globals are convenient and dangerous. Any code anywhere can change them, so bugs are hard to trace; tests interfere with each other; and threads race on them. Large codebases prefer passing a struct (like a Config *) to the functions that need it. Globals are at their best when they're const.

Your turn: declare max_rounds with extern above main so it can be used before the definition that appears later in the file.

Previous: static functions and variables Next: const-correct interfaces