A C source file is plain text with no header, signature or version mark. Nothing in the file says which standard it was written for. The compiler reads the bytes, works through eight translation phases, and produces an object file. These pages cite clause numbers from C17 (ISO/IEC 9899:2018), which has the same numbering as C11.
Files and translation units
The C standard does not talk about .c and .h files. It talks
about source files. A source file together with everything it includes through
#include is a preprocessing translation unit. After preprocessing it
is a translation unit, and that is what the compiler compiles (C17 5.1.1.1).
Translation units are compiled separately and joined by the linker.
The file extensions are conventions of compilers and build systems, not part of the language:
| Extension | Holds |
|---|---|
.c | A C source file, compiled as one translation unit |
.h | A header, meant to be included by other files. Standard library headers need not be real files |
.i | C source after preprocessing, written by GCC and Clang with -E or -save-temps |
.s, .S | Assembly produced from C (.s), or assembly to be preprocessed first (.S) |
.o, .obj | The object file made from one translation unit |
On systems with case-sensitive file names, a capital .C usually means C++.
GCC treats it that way.
After preprocessing, a translation unit is a sequence of external declarations (C17 6.9):
translation-unit:
external-declaration
translation-unit external-declaration
external-declaration:
function-definition
declaration
The grammar needs at least one external declaration, so a file that is empty after
preprocessing is not strictly a valid translation unit. Compilers accept it, and GCC warns
with -pedantic. Statements cannot appear at file scope. Each
declaration and each
function definition stands directly in the
translation unit, and function definitions do not nest.
#include <stdio.h> /* preprocessing directive */
#define GREETING "Hello" /* preprocessing directive */
static int count; /* declaration: an object with internal linkage */
int next(void); /* declaration: a function prototype */
int main(void) /* function definition */
{
printf("%s %d\n", GREETING, next());
return 0;
}
int next(void) /* function definition */
{
return ++count;
}
The phases of translation
The standard describes translation as eight phases carried out in order (C17 5.1.1.2). A compiler may combine them as long as the result is the same. Several surprises in C come from this order, so it matters even when you only want to read the code.
| Phase | What happens |
|---|---|
| 1 | The bytes of the file are mapped to the source character set, in an implementation-defined way. End-of-line indicators become new-line characters. Until C23, trigraphs are replaced here too |
| 2 | Each backslash immediately followed by a new-line is deleted, joining two physical lines into one logical line |
| 3 | The text is split into preprocessing tokens and white space. Each comment is replaced by one space |
| 4 | Preprocessing directives are executed and macros are expanded. A file named by #include goes through phases 1 to 4 itself. All directives are then deleted |
| 5 | Characters and escape sequences in character constants and string literals are converted to the execution character set |
| 6 | Adjacent string literal tokens are concatenated |
| 7 | Preprocessing tokens become tokens, and the tokens are parsed and translated as a translation unit |
| 8 | External references are resolved. Translation units and library components are linked into a program image |
Some consequences of the order:
- Line splicing comes before comments are recognised, so a
//comment ending in a backslash continues onto the next line. - Comments are gone before macros are expanded, so a macro cannot make a comment, and
##cannot build one. - Comments are replaced before directives run, so a directive may contain a comment, and a
multi-line
/* */comment does not end the directive. - String concatenation comes after macro expansion, so a macro may expand to a string
that joins its neighbours. This is how the
<inttypes.h>format macros work:"%" PRId64.
// This comment ends in a backslash \
so this line is still part of the comment.
#define LONG_MACRO(a, b) \
((a) + (b)) /* two physical lines, one logical line */
const char *s = "first " "second"; /* one string after phase 6 */
Character encoding
The standard does not say how a source file is encoded. Phase 1 maps the bytes to source characters in an implementation-defined way, so the encoding is a matter for each compiler (C17 5.1.1.2, 5.2.1). A file carries no mark of its encoding, apart from an optional byte order mark.
| Compiler | Default source encoding | To change it |
|---|---|---|
| GCC | UTF-8 | -finput-charset= |
| Clang | UTF-8 | None; other encodings are not supported |
| MSVC | The system code page, unless the file has a byte order mark | /source-charset: or /utf-8 |
The basic source character set is the set the standard requires (C17 5.2.1):
- the 26 uppercase and 26 lowercase Latin letters;
- the 10 decimal digits;
- 29 graphic characters:
! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~; - the space, horizontal tab, vertical tab and form feed;
- some way of ending lines.
In C17 $, @ and ` are not in this set. Compilers
usually accept any character from the source encoding in comments and string literals.
Characters outside the basic set can be written in identifiers and literals with
universal character names such as é (see
Lexical structure).
The compiler converts string and character constants from the source character set to the execution character set in phase 5. These two may differ.
Line endings
Phase 1 turns each system’s end-of-line indicator into a single new-line character, so
the bytes that end a line are not part of the language. GCC accepts LF, CR LF and CR as
line endings, whichever system it runs on. A new-line ends a preprocessing directive, and
ends a // comment.
A source file that is not empty must end in a new-line that is not immediately preceded by a backslash; otherwise the behaviour is undefined (C17 5.1.1.2). Compilers accept such files and some warn.
Headers and include guards
A header holds what several source files need to agree on. It is included with
#include, whose effect is the same as pasting the text of the file at that
point (see #include).
The usual contents are:
- macro definitions;
- structure, union and enumeration declarations;
typedefnames;externdeclarations of objects and prototypes of functions;static inlinefunction definitions.
A header should not define an object or a non-inline function with external linkage. Every translation unit that included it would then define the same name, and the link would fail (see Tentative definitions).
A file may be included more than once, directly or through other headers. A repeated definition of a structure is an error, so headers protect themselves with an include guard, also called a header guard:
#ifndef MYLIB_POINT_H
#define MYLIB_POINT_H
struct point {
int x;
int y;
};
int point_distance(const struct point *a, const struct point *b);
#endif /* MYLIB_POINT_H */
point.h: the second inclusion finds the macro already defined and skips the whole file#include "point.h"
#include <stdlib.h>
int point_distance(const struct point *a, const struct point *b)
{
return abs(a->x - b->x) + abs(a->y - b->y);
}
point.c: the implementation includes its own header, so the compiler checks the two agreeThe guard’s macro name must be unique across every header in the program. Do not begin it with an underscore followed by a capital letter or a second underscore: those names are reserved.
#pragma once is a widely supported alternative. GCC, Clang and MSVC accept
it, but it is not part of the standard.
Translation limits
The standard requires a compiler to be able to translate at least one program that contains at least one instance of each of these limits (C17 5.2.4.1). Most compilers set no fixed limit, or a much higher one. C90’s lower limits are shown where they changed.
| Limit | C99 and later | C90 |
|---|---|---|
| Nesting levels of blocks | 127 | 15 |
| Nesting levels of conditional inclusion | 63 | 8 |
| Declarators modifying a type (pointer, array, function) | 12 | 12 |
| Nesting levels of parenthesised declarators | 63 | 31 |
| Nesting levels of parenthesised expressions | 63 | 32 |
| Significant initial characters in an internal identifier or macro name | 63 | 31 |
| Significant initial characters in an external identifier | 31 | 6, ignoring case |
| External identifiers in one translation unit | 4095 | 511 |
| Block-scope identifiers declared in one block | 511 | 127 |
| Macro identifiers defined at once | 4095 | 1024 |
| Parameters in one function definition | 127 | 31 |
| Arguments in one function call | 127 | 31 |
| Parameters in one macro definition | 127 | 31 |
| Arguments in one macro call | 127 | 31 |
| Characters in a logical source line | 4095 | 509 |
| Characters in a string literal after concatenation | 4095 | 509 |
| Bytes in an object, hosted environments only | 65535 | 32767 |
| Nesting levels of included files | 15 | 8 |
case labels in a switch | 1023 | 257 |
| Members in one structure or union | 1023 | 127 |
| Enumeration constants in one enumeration | 1023 | 127 |
| Nesting levels of structure or union definitions | 63 | 15 |
The limit for external identifiers matters for old code. A C90 compiler could treat
longname_a and longname_b as one symbol, because only the first
six characters had to count.