C:invisible mother tongue
In 1972 Dennis Ritchie reshaped B into C at Bell Labs to give the upcoming Unix "a high-level language fit for writing an OS." 53 years later every phone, every cloud VM, every GPU, every AI inference still runs on it underneath — you just don't see it.
53 years and counting
kernel.org · 2025
swapping with Python
Linux/BSD/XNU/Windows
What is C
C is a systems language: close to the hardware, near-zero runtime, manual memory management. It does not think for you — which is exactly why it fits everywhere between an 8-bit MCU and a supercomputer.
Pointers, addresses, byte sizes, alignment — all exposed. Each line of C maps almost one-to-one to machine instructions.
No GC, no VM, no reflection. A C program can be a 4 KB firmware blob or a kernel — the runtime is invisible.
You allocate, you free. This freedom buys peak performance — and most of the CVEs in software history. Rust exists to buy that insurance back.
Python, Rust, Go, Swift, Zig, Java JNI — every cross-language call rides on the C ABI. A 53-year-old foundation language.
# 1M float additions
def sum_array(arr):
total = 0.0
for x in arr:
total += x
return total
# interpreter + boxed ints + refcount
# → ~200 ms / 1M elems// 1M float additions
double sum_array(double *arr, size_t n) {
double total = 0;
for (size_t i = 0; i < n; ++i)
total += arr[i];
return total;
}
// gcc -O3 auto-vectorizes to AVX
// → ~0.3 ms — 600× fasterHistory : 1966 — 2026
BCPL → B → NB → C self-hosting on a PDP-11 → the K&R white book → ANSI standardization → Linux → C23. An unbroken chain.
- 1966
BCPL — the origin
Cambridge's Martin Richards designs BCPL, the "Basic Combined Programming Language." Simple, typeless, mostly used to write compilers and systems tools. C's grandfather.
- 1969
B at Bell Labs
Ken Thompson trims BCPL down to B for the early PDP-7 Unix. Still typeless — every variable is a machine word.
- 1971
NB — "New B"
Dennis Ritchie adds a
chartype to B so it can use the PDP-11's byte addressing, calling it NB (New B). The first time "types" enter this lineage. - 1972
C is born at Bell Labs
Ritchie adds pointers, arrays, and structs to NB, rewrites the compiler, renames it C. C bootstraps itself on the PDP-11. "The most creative period," in Ritchie's own words.
- 1973
Unix kernel rewritten in C
Thompson and Ritchie rewrite the Unix V4 kernel from assembly + B into C. The first time an OS is implemented in a high-level language — you cannot overestimate this moment.
- 1978
K&R first edition
Brian Kernighan + Dennis Ritchie publish The C Programming Language. That thin white book defines "K&R C" — the de-facto standard before formal standardization.
hello, worldtraces back to this book. - 1983
ANSI X3J11 starts
The American National Standards Institute starts X3J11, a six-year effort to formalize K&R C. The same year Bjarne Stroustrup wraps up "C with Classes" at Bell Labs — soon to be renamed C++.
- 1987
GCC 1.0 — engine of free software
March 22nd: Richard Stallman releases the first GNU C Compiler. C is no longer tied to any single vendor; the whole open-source movement now has a self-hosting toolchain. Linux grows out of this five years later.
- 1989/90
ANSI C / C89 / C90
ANSI ratifies X3.159-1989 in 1989; ISO adopts it almost verbatim as ISO/IEC 9899:1990. C now has its first international standard. To this day "I can write C89" is still a job requirement for most embedded jobs.
- 1991
Linus writes Linux in C
Linus Torvalds at the University of Helsinki posts that "I'm doing a free operating system (just a hobby, won't be big and professional)" mail. Language choice: C. Three decades later, 33 million lines of C run inside every Android phone and every cloud VM near you.
- 1999
C99 — the modern leap
ISO/IEC 9899:1999.
//line comments,inlinefunctions, variable-length arrays, compound literals,long long,<stdint.h>, designated initializers. Almost everyone writing C today lives on or above C99. - 2007
Clang / LLVM arrives
Apple funds Chris Lattner's LLVM project; Clang ships open-source as a C / C++ / Objective-C frontend. Modular, friendly diagnostics, fast builds — it shakes GCC's twenty-year monopoly. Today macOS, iOS / Xcode, and Tesla's autonomy stack all compile through Clang.
- 2011
C11 — catching up
ISO/IEC 9899:2011 (December 8th).
_Atomic, threads (<threads.h>),_Generic, anonymous structs/unions,_Static_assert. The multi-core era finally has a place in the standard. - 2018
C17 — maintenance release
ISO/IEC 9899:2018. No new features, only defect-report fixes against C11. Known as "C17";
-std=c17targets it. Mostly there to give C20 / C23 a clean baseline to build on. - 2024·02
C23 — still moving at 53
ISO/IEC 9899:2024, published February 22nd. Brings
nullptr, realtrue/falsekeywords,typeof,auto(C++-style type inference), binary literals0b, attributes like[[nodiscard]], UTF-8 strings. A 53-year-old language still evolving in earnest. - 2026
The invisible mother tongue
TIOBE 2026: C trades #1 / #2 with Python every other month; Linux kernel 33M lines of C; GPU drivers, CUDA runtime, cuDNN, every Python C-extension, PostgreSQL / Redis / SQLite / Nginx — every AI model forward pass goes through this stack of C libraries. Invisible, but always there.
The Core : TheEightThings
C has just 32 keywords; K&R covers the whole language in 272 pages. 90% of day-to-day code uses the eight primitives below — pointers, arrays, structs, function pointers, the preprocessor, manual memory, linkage, and that beloved-and-feared monster: undefined behavior.
Pointers
A variable is an address. Everything starts here: linked lists, trees, callbacks, references, runtime polymorphism, shared memory — anything other languages give you implicitly, C does explicitly with pointers.
int x = 42;
int *p = &x;
// p 指向 x 的地址
*p = 100;
// 通过指针写入 → x 现在是 100
printf("%d\n", x);Arrays ≈ pointers
An array name decays to a pointer to its first element. a[i] and *(a + i) are strictly equivalent — one of C's most elegant and most punishing design decisions.
int a[5] = {10, 20, 30, 40, 50};
a[2] // 30
*(a + 2) // 30 — 同义
2[a] // 30 — 也合法 (!)
// sizeof(a) = 20 (5*4)
// 但传入函数后退化为指针Structs
struct is C's only composite type. No methods, no inheritance — yet the Linux kernel models "object orientation" with structs full of function pointers.
struct Point {
double x, y;
};
struct Point p = { 3.0, 4.0 };
// C99 designated initializer:
struct Point q = { .x = 1, .y = 2 };
printf("%g\n", p.x);Function pointers
Functions are addresses too. Store them, pass them, table them — this is how C expresses "callbacks / strategies / vtables." signal handlers, qsort, the Linux file_operations table all rest on this.
int add(int a, int b) { return a+b; }
int (*op)(int, int) = add;
op(2, 3); // → 5
// qsort 接受比较函数指针
qsort(arr, n, sizeof(int), cmp);The preprocessor
Before compilation, cpp walks the text: #include pastes a header verbatim, #define performs literal substitution. C's "metaprogramming" — crude but extraordinarily flexible.
#define MAX(a,b) ((a) > (b) ? (a) : (b))
MAX(3, 7) // → 7
MAX(x++, y++) // 双重副作用 ⚠
#ifdef __linux__
// 仅 Linux 编译
#endifManual memory
malloc takes, free returns. C does not babysit — freedom plus responsibility. Forget to free → leak; free twice → double-free; use after free → UAF. This trinity is the source of countless CVEs.
int *arr = malloc(100 * sizeof(int));
if (!arr) return ENOMEM;
// ... 用 arr ...
free(arr);
arr = NULL; // 防 UAF 的好习惯Linking · extern · static
Each .c compiles to its own .o; the linker stitches symbols together by name. extern = "defined elsewhere"; static = "private to this file." This 50-year-old contract is why C is still the universal ABI for every other language.
// math.c
double G = 9.8;
static int helper(x) { ... }
// main.c
extern double G;
// helper 在这里看不见Undefined Behavior
Out-of-bounds reads, signed overflow, null deref, data races — all "undefined" per the standard. Compilers assume they never occur and optimize aggressively on that premise.
"UB isn't a bug — it's a contract. Breaking the contract costs anything the universe allows."
Why C : WhyC
Even if you don't write C, you should know what C is — because the Python / JS / Rust / Go you write every day all run on top of C.
Fast, always fast
No runtime, no GC, no VM. A line of C compiles to roughly the minimum machine instructions you can imagine. The ceiling is the CPU itself.
// gcc -O3 main.c
// → 直接出汇编,零开销Zero-cost abstraction, literally
C's abstractions — functions, structs, pointers — cost essentially nothing at the assembly level. Bjarne's "zero-overhead principle" was inherited from C.
// struct Point { double x, y; };
// 内存布局 = 16 字节, 对齐到 8
// 没有 vtable, 没有 headerThe universal ABI
C's calling convention is the lingua franca every language uses to talk to every other language. Python ↔ NumPy, Rust ↔ system APIs, Go's cgo, Node native modules — all sit on top of the C ABI.
// extern "C" — 用来对接
// Rust / C++ / Swift / Zig
// 都得发出 C 兼容符号Made for the metal
Kernels, device drivers, filesystems, bootloaders, microcontrollers, DSPs, power management chips — few languages let you touch memory, registers, and interrupts directly. C is the industrial standard.
// volatile uint32_t *GPIO_OUT
// = (uint32_t*)0x4002'0014;
// *GPIO_OUT |= 1 << 5; // LED 亮Compilers everywhere
From 8-bit MCUs to supercomputers, virtually every chip that runs code has a C compiler. GCC + Clang together cover hundreds of architectures — no other language comes close.
// avr-gcc, arm-none-eabi-gcc
// riscv64-gcc, xtensa-gcc...
// 你说出芯片名, 它有 C 编译器Small enough to fit in your head
K&R covers the entire language in 272 pages. 32 keywords, a few dozen standard-library functions. Learning C isn't learning syntax — it's learning how the machine thinks. A lesson nobody in our craft can really skip.
// 32 keywords total:
// auto break case char const ...
// while (没了)The blade of Undefined Behavior
Out-of-bounds access, null deref, signed overflow — all "undefined behavior" per the standard. This gives compilers room to optimize aggressively and gives programmers astonishing tail risk. C's sharpest edge.
// int x = INT_MAX + 1; // UB
// 编译器假设永远不发生
// 然后基于此优化, 出 bug 时
// 行为完全不可预测53 years of unbroken legacy
Unix tools written in 1973 still compile today under gcc -std=c89. Linux v0.01 (1991) still boots under modern GCC. This kind of backward compatibility is foundational to software civilization.
// gcc -std=c89 1973_unix_tool.c
// → 跑得好好的The bottom of the AI stack
NVIDIA driver / cuBLAS / cuDNN / NCCL / TensorRT / FFmpeg / OpenBLAS / MKL — every matrix multiply on a GPU eventually flows through kernels written in C / C++. Python is the thin glue on top.
// torch.matmul(a, b)
// ↓ Python C API
// ↓ libtorch (C++)
// ↓ cuBLAS (C)
// ↓ CUDA driver (C/asm)Who's Using : ProductionUsers
Every "boot / connect / play video / use AI" you do today flows through these 12 projects. Together they cover nearly everything.
C in the : AI Era
The languages on the AI hype train are Python and TypeScript. But you think AI runs on Python? It doesn't — AI runs on libraries written in C; Python is just glue. This chapter is about how the invisible mother tongue holds up the entire AI compute stack.
"The Unix philosophy is expressed in C — be simple, be composable, be close to the machine, don't think for the user. That philosophy hasn't changed in 50 years. It worked for operating systems, for compilers, for databases — and for every matrix multiply an AI model performs on a GPU today.
Linux mainline (kernel.org) is ~33-40M lines as of 2025; over 95% is C. Rust modules have been in since 6.1 (three+ years now), still under 2%. Every Android phone, every SteamDeck, nearly every cloud VM on Earth runs this pile of C.
NVIDIA driver, CUDA runtime, cuBLAS, cuDNN, NCCL, TensorRT — not a single layer is Python. Every PyTorch matmul call eventually drops into a kernel left behind by generations of C programmers.
2024-2025 TIOBE: C and Python keep trading the top two slots. At 53, this language isn't leaving — it's so foundational its presence gets overlooked because "it's just running."
Linux Kernel
Linus Torvalds started writing it in C from a dorm in Helsinki, 1991. Today ~33M lines of C, 70-80K commits a year, thousands of contributors. It runs Android, ChromeOS, SteamDeck, almost every Linux VM on AWS / GCP / Azure, and most embedded devices — every "thing that runs Linux" you can name.
- kernel/ — scheduling / interrupts / sync primitives — all C
- mm/ — memory management — all C
- fs/ — filesystems — ext4 / btrfs / xfs all C
- drivers/ — 60%+ of kernel LOC — almost entirely C
- rust/ — new Rust abstractions — under 2%, still experimental
In other words: the "operating system" on your device is essentially 53 years of unbroken C code.
// linux/kernel/sched/core.c — simplified
struct task_struct {
volatile long state;
void *stack;
unsigned int cpu;
struct mm_struct *mm;
struct files_struct *files;
// ... 数百字段 ...
};
static void __schedule(bool preempt) {
struct task_struct *prev, *next;
// 选下一个要跑的任务
next = pick_next_task(rq, prev);
context_switch(rq, prev, next);
}
// This is the code your machine is runningC toolchain · industrial-grade and stable
The full path of one GPU matmul
You write torch.matmul(a, b) in Python, one line — but the stack underneath is dizzying.
Every layer is engineering left by generations of C / C++ programmers. Each AI forward pass re-traces this decades-old path.
"The AI era doesn't need C" makes for a tidy headline. The truth: the AI era runs at all because the 53 years of C underneath are stable.
// What Python shows you:
y = torch.matmul(a, b)
// ↓ Python C API (C — CPython)
// ↓ libtorch (C++ — pybind11)
// ↓ ATen dispatcher (C++)
// ↓ cuBLAS gemm kernel (C)
// ↓ CUDA driver (C / asm)
// ↓ NVIDIA GPU SM tensor core
// 6 layers down, the actual math is C
// Your Python is just the triggerSummary, one line: C isn't the AI era's past tense — C is the infrastructure that lets the AI era exist. Every GPT response, every video generation, every chip waking up, every kernel interrupt — it's all running on it.
vs : C vs C++ vs Rust
C is the foundation; C++ piles abstraction on top of that foundation; Rust re-pours the foundation as memory-safe concrete. All three target the same class of problems — systems programming — but they take very different paths.
| C | C++ | Rust | |
|---|---|---|---|
| Born | 1972 | 1985 | 2010 |
| Design goal | Write an OS | C + classes + templates | Safety + systems |
| Memory | manual malloc/free | manual / RAII / smart ptrs | compile-time borrow checker |
| Memory safety | None — programmer's job | Partial — smart ptrs / RAII | Compile-time guaranteed |
| Abstraction level | Very low · 32 keywords | High · OOP + templates + concepts | Medium-high · traits + generics |
| Build speed | Very fast | Slow · template bloat | Slow · borrow check + LLVM |
| Learning curve | Easy syntax, hard to use right | Steep · decades of features | Steep · borrow checker frustration |
| OS kernel / drivers | De facto standard | Rare · banned in many kernels | Linux 6.1+ accepts it |
| Embedded / MCU | 95%+ | Some (RTOS / automotive) | Growing, still small |
| ABI universality | Lingua franca for all languages | Poor · name mangling varies | Needs extern "C" |
| Main risk | UB / memory errors | All C risks + complexity blowup | Fighting the compiler |
| 2026 status | Irreplaceable foundation | Games / browsers / HFT | Default for new systems work |
Outlook : TheRoadAhead
"Will C be replaced by Rust?" Short term: no. Medium term: more new code will be Rust, but the gigantic existing C codebase isn't going anywhere; migration cost is astronomical. A 53-year-old language doesn't vanish because something better appears — it becomes infrastructure, as foundational and as undiscussed as rebar.
C23 — still growing at 53
For a language to land a major revision every 5-10 years across 53 years is itself a miracle. C23 is not just patches: nullptr, real true/false keywords, standardized typeof, auto repurposed for type inference, binary literals 0b1010, [[nodiscard]] attributes, UTF-8 string literals.
What matters more is the attitude: the committee is still seriously modernizing C. That cuts against every "C is dead" take. GCC 14 / Clang 18+ already implement most of C23.
Linux is still C — Rust knocking
Linux 6.1 (Dec 2022) accepted Rust modules. By late 2025 the Rust portion is ~600K lines — still under 2%. Linus' stance: "C remains the language of Linux. We're just letting new drivers be written in Rust."
Translation: for the next 10-20 years inside the kernel, C is still dominant.
AI inference's bottom is all C/C++
NVIDIA driver, CUDA runtime, cuBLAS, cuDNN, NCCL, TensorRT — plus OpenBLAS, MKL, FFmpeg — three layers down the GPU stack and you are firmly in C.
So: every GPT call, every generated video frame, every YouTube playback ultimately runs through code left by generations of C programmers.
Embedded / IoT — C's private kingdom
8051 / AVR / STM32 / ESP32, automotive ECUs, rocket flight controllers, pacemakers — anywhere "chip runs code directly, no OS or just an RTOS" — C still owns 95%+. Rust is chasing, but toolchains / certifications / vendor SDKs still all default to C.
TIOBE: trading #1 / #2
2024-2025: Python and C swap the top two slots repeatedly on TIOBE. For a 53-year-old language this is roughly the best chart you can ask for.
Read it correctly: C isn't fading — it's so foundational it gets overlooked because "it's just running."
LLMs writing C, surprisingly well
C has a vast public code corpus (Linux + glibc + thousands of OSS projects); LLMs have ample training data. Plus the standard barely moves — asking AI for "a C89/C99 driver" is far more accurate than for niche languages.
The combination: humans hand-write less and less C, while AI's ability to write C for you keeps improving.