The C Landscape: What Is C, What It Is Not
Before writing a line of C, you need an accurate mental model of what C is. This chapter draws the boundaries that the rest of the document depends on.
Why This Matters
Most confusion in C comes from conflating the language with its environment. People say "C is portable," then write Linux-only code. People say "C is fast," then blame the language when their program does something the standard never promised. This chapter fixes those mistakes before they happen.
What C Is
C is a small, close-to-the-machine, statically typed, imperative programming language defined by an international standard. The current widely deployed standard is C17 (ISO/IEC 9899:2018); C23 is the next revision.
C was designed by Dennis Ritchie at Bell Labs in the early 1970s to implement Unix. Its defining design goal was to give programmers fine control over memory and machine behavior while remaining portable across hardware.
Three properties define C in practice:
1. Small language. The core language has a small number of keywords (C17 defines 44) and very few built-in operations. Most of what you need comes from the standard library or platform APIs.
2. Explicit memory. Memory is not managed for you. Allocation, deallocation, and the distinction between address and value are explicit.
3. Close to the machine. C's abstractions — integers, pointers, arrays, structs — map directly onto what real CPUs do. There is little hidden machinery between your code and the hardware.
What C Is Not
C is not a batteries-included language. It has no garbage collector, no built-in strings as first-class objects, no exception mechanism, no reflection, no module system, no dynamic dispatch, and no runtime type information.
C is not a platform. Sockets, threads, files, and processes are not C. They are provided by operating systems. Some are standardized by POSIX; others are specific to Linux, Windows, macOS, or an embedded RTOS.
C is not automatically safe. The standard explicitly leaves a large set of programs as having *undefined behavior*. It is your job to stay inside the defined subset.
C is not always portable. It is portable across *conforming implementations* only when you write to the standard's guarantees and avoid implementation-defined and undefined behavior.
The Layers You Must Keep Separate
Real C systems are built from several distinct layers:
+------------------------------------------------------------+
| Application code (your C program) |
+------------------------------------------------------------+
| Third-party libraries (SQLite, OpenSSL, SDL, ...) |
+------------------------------------------------------------+
| ISO C standard library (stdio, stdlib, string, ...) |
+------------------------------------------------------------+
| Platform API (POSIX / Win32 / RTOS / bare-metal) |
+------------------------------------------------------------+
| Operating system kernel (Linux, Windows, macOS, RTOS) |
+------------------------------------------------------------+
| Hardware (CPU, memory, peripherals, devices) |
+------------------------------------------------------------+
A key rule for the rest of this document:
> Never mistake a platform API for ISO C.
For example, printf is ISO C. open, read, write, mmap, fork, and socket are POSIX (or platform-specific), not ISO C.
The C Standard Versions
The C language has evolved through several standard revisions. Understanding which revision a feature comes from prevents a very common category of bug: using a feature on a compiler that does not support it, or assuming a feature is older than it is.
| Standard | Year | Informal name | Major additions / notes |
|---|---|---|---|
| ANSI C | 1989 | C89/C90 | The first formal standard; the baseline everyone knows |
| C95 | 1995 | C95 | Mostly an amendment (wide characters, digraphs) |
| C99 | 1999 | C99 | // comments, stdint.h, VLAs, designated initializers, long long, _Bool, inline functions, mixed declarations and code |
| C11 | 2011 | C11 | _Atomic, threads.h, _Generic, _Static_assert, _Alignof/_Alignas, anonymous structs/unions, bounds-checking interfaces (optional) |
| C17 | 2018 | C17 | A bug-fix revision of C11; no new features |
| C23 | 2023 | C23 | nullptr, constexpr, improved _Generic, digit separators, #embed, bool/true/false as keywords, and more |
The baseline for this document is C17 because it is the most widely deployed stable standard. C23 features are labeled C23. When behavior differs by version, the text says so explicitly.
Hosted vs. Freestanding Implementations
The C standard defines two execution environments:
- Hosted: a complete environment with an operating system and the full
standard library. Most applications, CLI tools, servers, and desktop programs run hosted.
- Freestanding: a minimal environment without an OS and with a reduced
standard library (typically just a few headers like <stddef.h>, <stdint.h>, <limits.h>, and <stdalign.h>). Embedded firmware and OS kernels are typically freestanding.
This distinction matters enormously. In a freestanding environment, you cannot assume printf, malloc, or even a stack in the usual sense. Part 13 (Embedded C) covers this in depth.
The Abstract Machine
C is defined in terms of an *abstract machine* — an idealized execution model described by the standard. A conforming compiler must produce a program whose *observable behavior* matches what the abstract machine specifies, but it is free to do anything else internally.
The observable behavior is a small set of things: reads and writes of volatile objects, calls to library I/O functions, and the termination status.
This is the single most important idea for understanding optimization. When a compiler "optimizes," it is allowed to eliminate or reorder anything that does not change observable behavior. Chapter c.core.2 and Part 2 develop this fully. For now, hold this thought: the compiler is your silent collaborator, and it assumes you never invoke undefined behavior.
The Machine Reality
C's types map closely to hardware:
| C concept | Hardware reality |
|---|---|
| integer types | CPU registers and memory words |
| pointers | memory addresses (plus provenance, in the object model) |
| arrays | contiguous regions of memory |
| structs | contiguous memory with padding for alignment |
| function call | stack frame + register/stack argument passing |
volatile | forces a real load/store; used for MMIO |
But this mapping is a *tendency*, not a guarantee. The standard describes semantics; the hardware describes implementation. Part 7 covers the mapping in detail.
Why C Is Still Everywhere
C remains the implementation language of the world's infrastructure:
- Operating system kernels (Linux, Windows NT core, macOS/XNU, RTOS kernels).
- Language runtimes and virtual machines (CPython, Lua, Ruby, many JS engines).
- Databases (SQLite, PostgreSQL core).
- Networking infrastructure and embedded firmware.
- Compilers and tooling (GCC, Clang, LLVM's C-facing layers).
- High-performance libraries and cryptographic code.
The reasons are stable: C has a stable ABI, minimal runtime, predictable performance, direct memory control, and it can be called from nearly every other language (Part 17).
What You Will Build
By the end of this curriculum you will have written, in C: a calculator, a CLI utility, a text processor, a JSON parser, a memory allocator, a shell, TCP clients and servers, an HTTP server, a thread pool, an event loop, a database, a bytecode VM, an interpreter, a compiler, an emulator, embedded firmware, a bootloader, an RTOS application, and a driver.
That list is not aspirational. It is the project plan in architecture/PROJECT_PROGRESSION.md.
What You Should Now Know
- C is a small, close-to-the-machine, statically typed language defined by an
ISO standard.
- ISO C, the standard library, platform APIs, and hardware are distinct layers.
- The primary baseline is C17; version differences are labeled.
- Hosted and freestanding environments differ, and this matters for embedded.
- C is defined by an abstract machine whose observable behavior the compiler
must preserve.
- C's power comes from explicit memory and a direct mapping to hardware; its
danger comes from undefined behavior.
Progress
- [ ] Read
- [ ] Understand
- [ ] Complete examples
- [ ] Complete exercises
- [ ] Complete deep challenge
Concept checkboxes
(No language concepts are introduced in this orientation chapter.)
Mastery levels
| Concept | Current level (0–8) | Target level |
|---|---|---|
| (C's layers and standard versions) | 0 | 2 |
Verification
- The standard-version table is consistent with the ISO C standard timeline.
VERIFIED
- The hosted vs. freestanding distinction is defined in the C standard.
VERIFIED
- The list of C23 features is representative, not exhaustive. `PARTIALLY
VERIFIED`
- No code examples appear in this chapter; no execution verification required.
Related Concepts
- Next:
c.core.1— Program Structure, Translation Units, and the First
Program.
- Later:
c.core.2— Objects, Values, and the Abstract Machine. - Later:
c.embedded.1— The Embedded Landscape (freestanding detail).