The C Standards: K&R, C89, C99, C11
What This Concept Is
"C" is not one language. It is a sequence of standards, each specifying what a conforming C compiler must accept and what it means.
Milestones you will meet in practice:
- K&R C (1978) - the language described in the first edition of Kernighan & Ritchie. Old-style function declarations, no prototypes, no
void, implicitint. - C89 / C90 (ANSI X3.159-1989, ISO/IEC 9899:1990) - the first standard. Prototypes,
void,const,volatile, standard library locked in. This is the second-edition K&R book. - C99 (ISO/IEC 9899:1999) -
//line comments, mixed declarations and code, variable-length arrays (VLAs),inline,long long,<stdint.h>,<stdbool.h>, compound literals, designated initializers. - C11 (ISO/IEC 9899:2011) -
_Static_assert,_Generic, anonymous structs/unions, atomic types, threads (optional),getsremoved,fopen_s/gets_soptional in Annex K. - C17 (ISO/IEC 9899:2018) - bug-fix revision of C11, no new features.
- C23 (ISO/IEC 9899:2023) -
nullptr,constexpr,boolas keyword,[[attributes]], binary literals, improved<stdbit.h>. Compiler support is still landing.
For this module, default to C11 with gcc -Wall -Wextra -std=c11. K&R's second edition is your primary text; it tracks C89 closely. Flag anything that requires C99 or later explicitly.
Why It Matters Here
You will read code from all four eras:
- legacy embedded and Unix code is often K&R or C89
- most Linux kernel code is C89 with GNU extensions
- modern application C targets C99 or C11
- research and security code is migrating to C11/C17
If you cannot tell which era a snippet is from, you will miss both its bugs and its idioms.
Concrete Example
Same function, four eras:
K&R style (do not write new code like this):
int sum(a, b)
int a; int b;
{ return a + b; }
C89/C90:
int sum(int a, int b) { return a + b; }
C99 (new features):
int sum(int a, int b) {
int result = a + b;
for (int i = 0; i < 1; i++) { /* mixed decl + code, `int i` in for */ }
return result;
}
C11 (new features):
#include <assert.h>
_Static_assert(sizeof(int) >= 4, "need 32-bit int");
int sum(int a, int b) { return a + b; }
Common Confusion / Misconception
"// comments have always been in C." They were only standardized in C99. If you see a textbook that rejects them, it is C89 era.
"C and C++ are almost the same." They diverged at C89. Writing in the "common subset" costs both languages their natural idioms. Pick one per project.
How To Use It
- Decide the standard at the start of a project and add
-std=c11(or equivalent) to the build. - When reading older code, silently translate: "implicit
int" means "this was C89 or K&R." - When writing, prefer the most recent standard your toolchain supports without compromising portability targets.
- Do not mix K&R function definitions with modern prototypes in the same file - most compilers now warn or error on that combination.
Check Yourself
- Which standard introduced
//comments,long long, and<stdint.h>? - Which standard removed
gets? Why? - What is "implicit
int" and why is it dangerous?
Mini Drill or Application
Given the function int f(a, b) int a; int b; { return a * b; }:
- Rewrite it in C89 prototype style.
- Rewrite it in C99, and add a
_Boolreturn value for whether the product overflowed. - Add a C11
_Static_assertthatsizeof(int) == 4. - Compile each form with
gcc -std=c89 -Wallandgcc -std=c11 -Walland list the warnings.