C / CHAPTER 09

Headers, linkage, and separate compilation

Intermediate

Expose one consistent interface across translation units.

By the end of this chapter

  • Separate declarations from definitions
  • Use include guards
  • Keep private helpers local to a source file

The idea

A C program can be compiled from multiple source files, each forming a translation unit after preprocessing. A header publishes declarations that callers and implementations should both include. Keeping one shared declaration prevents subtly different parameter or result expectations from being copied into separate files. Compilation checks a translation unit; linking resolves the external definitions used across them.

An include guard prevents repeated contents within one translation unit. It does not make repeated external variable definitions across different source files harmless. Declare shared objects with extern in a header and define them in one source file when global state is truly needed. Mark a file-private function static to give it internal linkage. Prefer passing state explicitly over adding unnecessary global variables.

C example
/* scale.h */
#ifndef SCALE_H
#define SCALE_H
int twice(int value);
#endif
/* scale.c */
#include "scale.h"
int twice(int value) { return value * 2; }
/* main.c */
#include <stdio.h>
#include "scale.h"
int main(void) { printf("%d\n", twice(7)); }
Result
14 when the two source files are compiled and linked together.

The header shares a declaration; scale.c supplies the one external function definition.

Try it yourself

Split a checked arithmetic helper into a guarded header, implementation file, and caller, keeping internal helpers static.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

What is the usual purpose of static on a file-scope helper function?