Detailed contents
The contents opened out to the section level --- for going straight to a place.
Searches headings and index terms --- not the full text
Part I — Ground: the machine and its memory
1.1What is programming1.2Where C is1.3The world of C is changing a great deal right now1.4Why this book was made1.5How to read this book
2.1Drawing a computer as three parts2.2The bit — the smallest unit of information2.2.1Is binary the right answer mathematically, too?2.2.2A ternary computer that was actually built — Setun2.2.3So why did binary win?2.3C was born in the days of the simple three-part machine
3.1The locker corridor3.2The word — the machine’s natural handful3.3Endianness — two orders for putting a number in several slots3.4Is the locker number a real address?3.5The archetype of C is in the locker corridor
4.1What is in locker 04.2The three nulls — three things alike only in name4.3Alignment — a two-slot load cannot go just anywhere4.4The trick of the low bits — tagged pointers
5.1Four regions, one metaphor5.2Why the static region divides in two — the strange name bss5.3Static, stack and heap: the three regions contrasted5.4How far this sketch holds5.4.1The standard has no word “stack”5.4.2Machines that really are different — today5.5Where this sketch will be used
Part II — What the machine really is: representation and execution
6.1Unsigned integers — numbers that go round like a clock6.2Three agreements for holding negative numbers6.3The competition of the three, and C23′s decision6.4Shift — pushing bits wholesale6.5Sign extension — from a narrow container to a wide one6.6Seeing integer bits with your own eyes
7.1Fixed point — pinning the decimal point down by agreement7.2Floating point — carrying the point in the data7.3How the bits are really divided7.4Three incidents caused by approximation7.5The chaos, and the contract called IEEE 7547.6Seeing floating-point approximation with your own eyes
8.1A character is a number8.2ASCII and EBCDIC — two tables8.2.1What “the alphabet is not consecutive” does to code8.2.2Which is why there are libraries — what an abstraction does8.3ISO 646 — national variants and C’s trigraphs8.4Many eight-bit tables, and Hangul8.5Unicode and UTF-8 — one table, a clever way of holding it8.6The two character sets C keeps apart — source and execution8.6.1Where source characters cross into the execution character set — translation phases 1 and 58.6.2The more precise name C23 added — the literal encoding8.6.3Prefixes that nail the encoding down8.7Same letter, several representations — the security terrain hidden in text8.8Sequences of characters — ways of holding a string
9.1Punched cards — one card is one line9.2Line printers — output by the line9.3Printing terminals — a conversation on paper, and tty9.4Screen terminals, and streams as the legacy9.5There are tubs along the band — buffers9.6Swapping the band — redirection and pipelines
10.1A program is a noun, a process is a verb10.2How a process is born10.3The life of a process10.4User mode and kernel mode — what may be done and what may not
11.1One core, several jobs — the idea of taking turns11.2When to cut off — four candidates11.2.1Why a program giving way of its own accord is not enough11.3The kinds of multitasking11.4What is carried across a switch — the context11.5Who announces the moment to switch — the timer interrupt11.6The wires to a device — one after another, or all at once11.7When the outside speaks11.7.1When several things interrupt11.7.2What “asking the device” actually means11.7.3When another interrupt arrives mid-handler — how code copes11.8How the two differ — interrupts and multitasking11.9Interrupts were once almost everything a personal computer did11.10Where interrupts and multitasking survive today
12.1A confession — the CPU-memory-clock picture was too simple12.2Registers — the CPU’s own hand, there all along12.3The widening gap — between register and memory12.4The cache — a middle layer wedged into the gap12.5The cache divides — a ladder of layers12.6Measuring the cache — same number of reads, different order12.7Another ladder — virtual memory12.7.1From segments to paging12.7.2The TLB — the translation gets a cache too12.7.3Page faults, and lazy memory12.7.4Protection — why a null dereference usually dies at once
13.1The pipeline — instructions on an assembly line13.2Branch prediction — guessing which way the road forks13.3Measuring branch prediction — an easy condition and a hard one13.4The limit of the clock, and multicore13.5The same era: C wrote a contract — pre-standard C and C8913.6The places the contract does not cover — grey areas13.7When a standard outside C promises instead
14.1The editor’s workshop — what a compiler does14.2The abstract machine — the virtual machine inside the contract14.3Visible edits — when a value is read and when it is written14.4Refining the contract — C99, C1114.5A false signal to the compiler — the ghost summoned by breaking strict aliasing
15.1Completing the thesis — memory, execution and the compiler put together15.2The current direction — pointers acquire an origin15.3A closing panorama — which machine’s language is C?15.4Closing Part II
Part III — The first program
16.1The first program16.2The terminal and the shell — where a program is run16.2.1Which terminals (windows) and which shells (workers)16.2.2What a shell does — read, split, run16.2.3Running the executable you made16.2.4Passing arguments — how a program is handed values16.3Compiling and running from the command line16.3.1GCC (Linux, macOS, MinGW)16.3.2Clang (the macOS default; Linux and Windows too)16.3.3MSVC (Windows)16.4And so the first program comes out like this16.5Reading it line by line16.6But what happened between source and execution?
17.1From outside — a single command17.2Runner 1 — preprocessing: patchwork on text17.3Runner 2 — compiling: C into assembly17.4Inside runner 2 — the lexer and the parser17.5Runner 3 — assembling: stamping out machine instructions17.6Runner 4 — linking: joining pieces and filling holes
18.1Only three things are needed — a compiler, an editor, a terminal18.2If installing is too much — try it straight in a browser18.2.1Study options — the same on the web18.3Warnings — leave the free review switched on18.4When Korean text breaks — the chain of encodings18.4.1Nailing down the source encoding (②) and the execution character set (③) for the compiler18.5The debugger — stopping to look inside18.6Debug-build options — -g and -O0 are different switches18.7The debugger’s blind spot — optimised builds18.8“It works in debug but is wrong only in release”18.9Tools for when the debugger cannot be trusted18.10Sanitizers — a net cast while the program runs18.11What we have set up so far — the first program, the compilation process, the tools
19.1The big three — GCC, Clang/LLVM, MSVC19.2The compilers that sell performance — vendor compilers19.3Embedded — the doorway to a later chapter19.4An aside — Pelles C, the tidy alternative on Windows19.4.1Writing a Windows app in C19.4.2What comes in the one package — the resource editor and dialog designer19.5Others, and the retired names19.6Where each compiler’s official material lives
Part IV — A minimal toolbox
20.1Comments — writing only humans read20.2Statements — one step, and the semicolon20.3Blocks — a bundle of statements20.4Lines that are not statements — the world of #20.5Putting it together — a two-statement program
21.1Values and how they are written — what this chapter covers21.2Literals — values written in source21.3Writing constants — all of them at a glance21.4Integer constants (§6.4.4.1)21.5The C23 digit separator '21.6Character constants (§6.4.4.5)21.7Floating constants (§6.4.4.3)21.8String literals (§6.4.5)21.9Things that look like constants21.10constexpr — the real constant C23 brought in21.10.1What it is you are writing21.10.2How it differs from const21.10.3The value has to fit exactly21.10.4What happens at file scope21.11Expressions — the things that are evaluated into values21.12Order — precedence, and the practice of parentheses21.13One caution planted early — the order in time may differ
22.1The call — say the name and a worker runs22.2The return value — used, or discarded22.3The standard library — workers made in advance
23.1What output is — how a program speaks to the outside23.2printf — output with a format23.3Kinds of blank — a slot per kind of value23.4Lining things up — width and precision23.5Output has more than one window23.6Matching — the contract between format and materials23.7Closing Part IV — rereading hello world
Part V — Declarations: how names are made
24.1What a variable is — a named slot24.2Declaration — type, name, and a first value24.3Assignment — the side effect that changes state24.4const — the promise not to change
25.1Making a worker — declaration and definition, again25.2Definition — the syntax for making a worker25.3Declaration — only the signature, in advance25.4One more word a declaration takes — inline25.4.1inline is a request, not an order25.4.2An inline function’s address can be taken — and that is when a real body is needed25.4.3C’s inline model — one rule and its consequences25.4.4So in practice an inline function takes only two forms25.4.5Two restrictions on an inline definition25.5Scope — the range in which a name is visible25.6Settling the credit — int main(void)
26.1What input is — taking values in from outside26.2Two stages — read, then interpret26.3The contract of fgets — what it gives, and what it leaves to you26.3.1How do you know the line fgets read was cut?26.4What stays in the input buffer (the tub) — a formatted read predicts, takes, leaves26.5Interpretation can fail26.6Closing Part V
Part VI — Values and control
27.1The four things a type settles27.2The first division — object types and function types27.2.1Complete and incomplete types27.3The basic types27.3.1There are three character types27.4Integer, real, arithmetic — the collective names27.5Derived types — made out of what is there27.6Qualifiers — a qualified edition of the same type27.6.1A qualified edition is the same size as the original27.6.2Qualifiers go in any order and may be combined27.6.3Only _Atomic has two faces27.6.4A qualifier is a property of the route, not of the value27.6.5A qualifier may be added silently, never removed27.6.6Where const attaches flips the meaning27.7Types with their width in the name — <stdint.h>27.7.1The three families of <stdint.h> types differ in what they demand of the width27.7.2The three traps of uint8_t27.7.3So which integer type do you use27.8Summary — the standard’s words and this book’s chapters
28.1The family of integer types28.2The basic types at a glance — minimum and actual ranges28.3The type of an integer constant — the same value, typed by its notation28.4Where size is the contract — fixed-width types28.5Seeing the boundary of an integer type with our own eyes
29.1Division and remainder — which way the fraction is discarded29.2Bit operations — chapter 6′s world, in C’s syntax29.3The contracts the integer operators make29.4Conversion — crossing between containers
30.1Rule 1 — integer promotion30.2Rule 2 — the usual arithmetic conversions30.3Rule 3 — default promotions for variadic arguments
31.1bool — a type with two values31.2Comparison — expressions that make true or false31.3Logical operators — weaving judgements together
32.1Going one way or another — what it means for a program to decide32.2if — when the condition is true32.3switch — a board that forks by value
33.1What repetition is — the same work many times33.2The three siblings of the loop33.2.1Where do-while really wins — counting backwards33.3The invariant — how a loop is trusted33.3.1Checking an invariant in three pieces33.3.2How people actually use the word “invariant”33.3.3Binary search — where the invariant earns its keep33.3.4What an invariant buys33.4for’s first slot — what may be declared there33.4.1How far a first-slot name is visible, and how long it lives33.5The condition slot is code, not a test33.6Loops that never end33.7Nested loops — double, triple33.8The reunion — Duff’s device
34.1Copying values — the original is safe34.2“Call by value” and “call by reference” — pinning the terms down34.3Side effects and evaluation order — collecting the seed34.4Recursion — a function that calls itself34.5Part VI’s last operator, ?:, and the seed of the contract34.6Operators at a glance — what we have met so far
35.1Assignment is an expression, not a statement35.2Assignment does three things35.3The left side is evaluated too35.4Compound assignment — the left side is evaluated once35.5Where the contract ends35.6The conversion hidden in an assignment
Part VII — Memory
36.1Three words first — object, address, pointer36.1.1Object — a region of memory that holds a value36.1.2What is an object and what is not36.1.3What every object has36.1.4A value or a place — the lvalue view36.1.5Address — where an object sits36.1.6Pointer — holding an address as a value36.1.7The three words at once — a demonstration36.2Three notations — declaration, &, *36.3sizeof — asking the size of a container36.3.1The type sizeof yields — size_t36.4What kind of number is an address — name, size, order36.4.1Why addresses are integers, of all things36.4.2The abstraction around pointers has thickened with time36.5How to print an address36.5.1The exact contract of %p36.5.2When an address has to become a string — uintptr_t and PRIxPTR36.5.3But — does the address need printing at all?36.6The size of a pointer is not one number
37.1What null is — “points at nothing”37.2nullptr — the name of emptiness37.3How far may 0 be used — the exact definition of a null pointer constant37.3.1The bits a null pointer becomes are another matter37.4The trap — code that assumes the representation is 0
38.1Alignment and casts — the privilege of char*38.1.1The privileges of void * and char * side by side38.2Provenance — the same number, a different origin38.2.1Provenance — a word that is not in the standard yet38.2.2Where was the gap — two neighbouring variables38.2.3Where the word “provenance” was born — DR26038.2.4Writing provenance down — from a questionnaire to a technical specification38.2.5What changes if the provenance model lands38.2.6Machines that carry the origin in hardware
39.1What an array is — when there are many of the same thing39.2The rigorous definition — how the standard writes an array39.3Declaration and initialisation39.4What arrays cannot do — assign, compare or return as a whole39.5Counting elements and traversal39.6Arrays and pointers — the truth about decay39.7There is no gap between one element and the next39.8Adding to a pointer is not ordinary addition39.8.1Three integer types that go with pointers — ptrdiff_t, intptr_t, uintptr_t39.8.2How far it may go — the contract of the arithmetic39.9An array parameter is not an array39.10Arrays whose size is settled at run time — VLAs39.11[static N] in a parameter — “at least this many will arrive”39.11.1[static 1] — writing “not null” into the declaration39.11.2A qualifier inside the same brackets qualifies the pointer39.12The boundary — the life-or-death rule39.13Accidents with arrays — security and memory problems39.13.1① One past the end — a single <=39.13.2② Write overflow — covering the neighbour39.13.3③ Read overflow — memory that leaks out39.13.4④ Negative subscripts — half a check39.13.5⑤ Uninitialised arrays — memory someone else used39.14Layers of defence — what to switch on and what to make a habit
40.1What a multidimensional array is — holding tables and grids40.2An array of arrays — the substance first40.3How a subscript unfolds40.4Parameters — why it is not int **40.5One address, different eyes — the contract of flattening40.6The patterns of practice40.6.1Flat plus a leading dimension — the lingua franca of numeric libraries40.6.2An array of row pointers — binding scattered rows into one40.7Traversal order and the cache — why the same computation differs several-fold40.8Accidents with multidimensional arrays40.8.1① A subscript past the row end — not an error, another cell40.8.2② Overflow in the flat index40.8.3③ Big local arrays — not enough stack40.8.4④ Parameters that take the size separately — a lie goes unnoticed
41.1Why this chapter has to exist41.1.1Why the misunderstanding is so tough41.1.2And discovery comes late41.2What differs — five axes41.3Steps to reach it — this is the real difference41.4The accident that crosses a file boundary41.5When they do become the same — three rules41.6The places that do not decay41.7Why 6[a] is legal41.8Parameter conversion happens one layer only41.9Three working patterns — seen with addresses41.9.11. An array of pointers — tying together things of different lengths41.9.22. A pointer to a pointer — where someone else’s pointer is changed41.9.33. Changing the order without moving the data41.10Passing multidimensional arrays of any size — what C could not do, and what C99 half-solved41.10.1What C99 changed41.11Accidents that decay causes — security and memory problems41.11.1① The sizeof mistake — a secret only partly wiped41.11.2② Bytes versus elements — a fourfold overflow41.11.3③ Returning the address of a local array41.11.4④ Pointer arrays that rely on an end marker41.11.5⑤ The file boundary — the accident seen earlier41.12Choosing between an array and a pointer — judgement in practice
42.1Nested loops — walking a multidimensional array42.2Leaving nested loops42.3The two places goto is right42.3.1Place 1 — shedding several loops at once42.3.2Place 2 — gathering the cleanup of error handling42.4Making a macro one statement — do { } while (0)42.5Other idioms, and their traps42.5.1Walking backwards — i >= 0 is unusable with size_t42.5.2The rest of the idioms
43.1What a string is — a line of characters and an end mark43.2What a C string really is — an array, and an agreement43.3String literals — read-only ground43.3.1A string literal’s type is not const — C’s odd place43.4A literal is an array too43.5Concatenation — adjacent literals become one43.6Prefixes — a literal of which encoding
44.1Dissecting the accident — the epidemic called the boundary violation44.2How the standard tools report failure44.3Five disciplines for handling a failed parse44.3.11. Return failure as a value44.3.22. Let the compiler speak when a check is forgotten44.3.33. Say how far it read44.3.44. Do not count truncation as success44.3.55. On failure, touch no output44.4Making the five parsing disciplines a component
45.1The standard’s four axes — storage duration, scope, linkage, storage class45.1.1Storage duration — four45.1.2Scope — four45.1.3Linkage — three45.1.4The seven storage-class specifiers — gathered in one place45.1.5The storage-class slot holds one — and its exceptions45.2Automatic and static lifetime45.3The layout of memory — the regions with our own eyes45.4The stack — the ledger of calls
46.1What dynamic memory is — memory borrowed at run time46.2Borrowing with malloc, giving back with free46.3How to write a malloc call — an old argument46.3.1Four reasons for form 1, taking the size from the target46.3.2The case for form 2, naming the type and casting — CERT MEM02-C46.3.3Form 3, the compromise, and the “C++ compatibility” reason — is it real?46.4The alignment of the address returned — because it does not know what will go in46.5The price of two cheap-looking lines, malloc and free — why allocation is expensive46.6Borrowing in one dimension, using it as two46.7Ownership — who is responsible for giving it back46.8Closing Part VII
Part VIII — The shape of data
47.1What a structure is — several attributes of one thing47.2The rigorous definition — read side by side with arrays47.3Declaration, initialisation, access47.4The first surprise of sizeof — not the sum of the members47.5Zeroing the whole thing — { 0 } and { }47.5.1What is actually guaranteed47.5.2The fine difference between {0} and {} — padding47.6A struct is a value47.6.1Why assignment works but comparison does not47.7Header and data in one block — the flexible array member47.7.1sizeof and offsetof — which one sizes the allocation47.7.2So can it be assigned? — copying a struct with a flexible array member
48.1Nesting and access — reading dots and arrows mixed48.2The temporary struct — the compound literal48.3Named arguments — passing one struct48.4Padding — the empty space between members48.4.1Why tail padding exists — the answer is “an array of structs”48.4.2Arrays of structs and pointers to them — the working patterns48.5Why a struct must not be stored or sent whole48.5.1So how is it done — field by field48.6How to remove padding, how to force alignment48.6.1alignas — the fifth family of the declaration’s front slot, the alignment specifier48.7Members without names, and container_of48.7.1Anonymous structs and unions (C11)48.7.2container_of — from a member back to the whole48.8Passing an array by value — can it be done, and should it?
49.1What a union is — taking turns in one place49.2The union — laying things over one another49.3Representation with our own eyes — endianness and padding49.4The active member and type punning — the same bits through another eye49.4.1Bit patterns that are not values — non-value representations49.4.2The size and alignment of a union, and the common initial sequence49.5Bit fields — cutting up one word49.5.1What the implementation decides about bit fields49.6The practical pattern of mixing structs and unions49.6.1One real specimen — two-byte Johab Hangul49.7On to the next chapter
50.1What serialisation is — sending a value outside50.1.1Four kinds of reader50.1.2Pointers cannot leave the process50.2Where serialisation can be avoided, and the price50.2.1Making the memory layout the format50.2.2Zero-copy formats — reading without copying50.3Techniques — cursors, sticky errors, fixed widths50.3.1Cursors — a struct that carries the room left50.3.2Fixed widths and shifts50.3.3Variable-length integers — small numbers, few bytes50.3.4Tag, length, value — skipping what you do not know50.3.5Sending floating-point values50.4Packing and padding — do not fit the struct to the format50.5Byte-order conversion — three ways50.6Buffer structures and their optimisation50.6.1Gather, then send once50.6.2A growing buffer50.6.3Ring buffers and double buffering50.6.4Leftovers in a reused buffer50.7Principles for designing a format50.8Security — every byte from outside was written by the other side50.8.1Accidents that happened50.8.2Structures that prevent them50.9Summary
51.1What data layout is — the same data, another order51.1.1Why order is speed51.2Measuring it — two jobs, three layouts51.2.1Hot fields and cold fields51.3Which wins, and when51.4The price of SoA51.5Cache-friendly data structures51.5.1The cost of following pointers51.5.2Cache-friendly data structures, by kind51.5.3Traversing matrices, and tiling51.6Cache-friendly algorithms51.7Practice in games and servers51.7.1Entity component systems51.7.2Servers51.7.3False sharing — again, as a layout problem51.8Security — the cache leaks secrets51.8.1Timing side channels — reading a table according to a secret51.8.2Speculative execution — a read that went past the bounds check51.8.3Hash-table flooding — trusting the average51.8.4Other dangers that come with changing the layout51.9The discipline of measuring51.10Summary51.11Closing Part VIII
Part IX — Deep corners
52.1Expressions in mathematics, expressions in C52.2The rigorous definition — expression, operator, operand52.3Side effects — what happens besides the value52.4The four things an expression carries52.5Precedence and associativity52.6Places where precedence trips people up52.7Prefix and postfix — the same job, a different value52.7.1The contract the standard sets52.7.2When the value is settled, and when memory changes52.7.3The truth of “prefix is faster”52.7.4Two things change in C++52.8Operator by operator52.9Postfix operators52.10Unary operators52.11Arithmetic operators52.12Shift operators52.13Relational and equality operators52.14Bitwise and logical operators52.15Conditional, assignment, comma52.16Evaluation order and sequence points52.16.1Three relations — before, unsequenced, one-or-the-other52.16.2Sequence points — “everything up to here is done”52.16.3The rule that leaves the contract — two unsequenced accesses to one object52.17The grey zones gathered52.17.1Undefined behaviour (UB)52.17.2Unspecified52.17.3Implementation-defined52.18Things that are not operators
53.1The five basic moves53.1.1Building masks, and the shift-width cliff53.2A set of flags — the commonest use53.3The idioms — and why they work53.4C23 — the idioms get names53.5Seven rules for working with bits53.6The accidents that happen around bit work53.7Before optimising by hand53.8In the flesh — where bits are used53.9Recap
54.1Choosing a type, and comparing54.2Special values — infinity and NaN54.2.1Opening the bits directly54.3The floor near zero — subnormal numbers54.3.1The hole you get with normal numbers alone54.3.2Two rules of interpretation change for subnormals54.3.3The price of subnormals — precision leaks at the floor54.4Security incidents at the floor54.4.1Incident 1 — stopping a server with one number54.4.2Incident 2 — slow arithmetic leaks secrets54.4.3Incident 3 — someone else’s library changes my arithmetic54.5IEEE 754 is not the only way
55.1Errors are values — C’s way55.2The contract in code — assert and defence55.3const — the cheapest contract
56.1The standard’s three categories — UB, unspecified, implementation-defined56.2Why undefined behaviour exists56.3The real face of “anything at all”56.4Before the computation even begins — the UB of a file’s shape56.5Other curious pieces of UB56.6UB you create on purpose — unreachable56.7How to avoid undefined behaviour — discipline, tools, and components56.8On to the next chapter
57.1What a memory error is — four promises57.2Breaking the size — buffer overflow57.2.1What overflows — five kinds57.2.2Why it is dangerous — it is not only data that is overwritten57.2.3The layers of defence57.2.4A buffer that carries its length57.3Breaking the lifetime57.3.1Leaks — losing the last pointer57.3.2Dangling pointers and use after free57.3.3Double free and invalid free57.3.4The address of an automatic object that has ended57.3.5realloc — the old pointer and size zero57.4Breaking initialisation and type57.4.1Indeterminate values — reading a place never written57.4.2Non-value representations — bits that are not a value of the type57.4.3Strict aliasing — seen again57.4.4The same bits through other eyes, inside the contract57.4.5Misalignment57.5Breaking provenance — provenance seen again57.6At a glance — UB, unspecified and implementation-defined on the memory side57.7What the tools catch, and what they miss57.8Summary — one line per accident
58.1What memory management is — who, and when58.2Habits for governing lifetime in C58.2.1One owner — written in names and comments58.2.2Pair each acquisition with its release, and clean up at one exit58.2.3Grouping things with the same lifetime58.2.4Why nullptr after freeing is half a fix58.3A data structure that detects dangling references — handles with generation numbers58.4Writing what was borrowed in a ledger — poisoning and quarantine58.5Reference counting — returning by counting58.6Tracing collection — is it reachable?58.6.1Mark-sweep58.6.2Copying collection — gathering while moving58.6.3Generational collection — most objects die young58.6.4Incremental and concurrent collection58.7What collectors cost58.8When the compiler tracks ownership58.9Attaching a collector to C58.10Closing Part IX
Part X — Structure and linkage: from files to declarations
59.1The three forms the standard permits59.2The contract of argc and argv59.3The value returned — three notations, one meaning59.4Conventions — who reads the exit status, and how
61.1Linking is not one step — three names61.2The real purpose of dynamic linking — not size but the ABI61.3What an ABI promises — item by item61.4What breaks an ABI61.5How to change it without breaking it61.6Position-independent code (PIC) — why libraries must be built this way61.7When names collide, a library function gets replaced — interpositioning
62.1What a scope is — not “where a name is visible” but “where it means that thing”62.2The four scopes62.3Where a scope begins — before the equals sign62.4Shadowing — the inner covers the outer62.5The preprocessor knows nothing of scope62.6Scope, lifetime, linkage — three that get confused
63.1The truth behind “C has no name spaces”63.2The four name spaces63.3Three axes — scope, linkage, name space63.4A habit born of tags living apart63.4.1typedef struct node node;63.4.2And yet there are conventions that forbid typedef63.5Enumeration constants are ordinary identifiers63.6Shadowing63.7Names you must not use — names reserved for the standard and the implementation
64.1When and where collisions go off64.2The first weapon — do not export (static)64.3The second weapon — the prefix convention64.4The third weapon — symbol visibility64.5The fourth weapon — cut down the names themselves64.6How C++ solved name collisions64.6.1The syntax64.6.2The anonymous namespace — the equivalent of C’s static64.6.3using namespace — the convenience and its price64.6.4ADL — looking in the yard of the argument64.6.5Name mangling and extern "C"64.7Good habits — a summary
65.1What the preprocessor is — the stage that edits text before compiling65.2Macros — turning a name into a stream of tokens65.2.1Parentheses — the first thing anyone using macros learns65.3# — turning a token into a string (stringize)65.4## — joining two tokens into one (token paste)65.5Double expansion — why one layer does not unfold65.5.1The names first — four macro-replacement rules65.5.2Following the expansion by hand — STR_RAW(WIDTH) against STR(WIDTH)65.5.3The standard’s own example — glue and xglue65.6The curious examples the standard gives65.6.1① Placemarkers — pasting an empty argument65.6.2② The expansion the standard declares “unspecified”65.6.3③ __VA_OPT__ — when is “empty” judged?65.7The X macro — several sets of code from one list65.8The translation phases — the eight steps the standard pins down
66.1Three things kept apart — declaration, definition, call66.1.1A call expression is an operator66.1.2Functions without prototypes, tidied away by C2366.2Arguments arrive as if by assignment66.3The order of argument evaluation — what the standard declines to fix66.3.1Where there is an order66.4One call, five steps66.5Register or stack — there is a budget66.5.1When the side that clears the stack differs, so does the symbol name66.6Strange cases — ARM and the embedded world66.7Passing and returning structures66.8Functions that return function pointers66.9The accidents that happen around a call66.10Recap
67.1What a variadic function is — a function whose number of arguments is not fixed67.2The four tools of <stdarg.h>67.3Default argument promotions — values crossing ... get fatter67.4The fundamental limit — a variadic function knows nothing about its arguments67.5_Generic — catching the type at compile time67.6proven’s PROVEN_ARG — the structure in the flesh67.7History — from varargs to stdarg
68.1What a function pointer is — “which function to call” as a value68.2The name decays into a pointer68.3The type is the contract68.4void * and function pointers are different worlds68.5How to print a function pointer68.5.1Why a function pointer cannot be passed to %p68.5.2The portable road — lift the bytes68.5.3The best answer — a name instead of an address68.6Dispatch tables — an array instead of a switch68.7The virtual function table — object orientation built in C
69.1The two readings69.2Reading ① in practice — connecting it in English word order69.2.1Reading ① has a name — boustrophedon69.2.2Reading by erasing69.3Reading ② — when there is no name69.4typedef — dividing into layers and naming them69.4.1Where to use typedef and where not to69.5The real thing — declarations that actually shipped69.5.1① The monster the standard itself produced — signal69.5.2② Rougher in the wild — X11′s error handler69.5.3③ And the genuinely pointless declarations69.6Leaving it to a tool — cdecl69.7Closing Part X
Part XI — Object-oriented programming imitated in C
70.1What object orientation is — first principles70.2C has none of it — it is imitation70.2.1Beware of “just do it well”70.3Separate the three parts — state, behaviour, table70.3.1Empty slots in the table70.4Opaque types — C’s version of encapsulation70.5Names — the prefix is the namespace70.6The first argument is the object — this by hand70.7The six chapters of this part70.8Summary
71.1Polymorphism — what it gives, what it costs, what to watch71.2Inheritance through tables — a derived table that embeds the base table71.3Overloading — one name, several bodies71.3.1Functions for the table, and functions not for it71.3.2Two ways to overload in C71.3.3The pros and cons of _Generic, and what to watch71.4Structs that survive new versions — writing the size into the struct71.4.1The rules to keep71.4.2Compared with the other ways71.5Lifetime — there is no RAII71.5.1Help from outside the standard71.6Summary
72.1Static tables and dynamic tables72.2The five steps of building a table72.2.1Sealing72.2.2Building once across threads72.3Where to keep the table pointer72.4Several interfaces, and finding them72.5Dispatch by name72.6Tables whose versions change72.7Summary
73.1What is measured, and how73.2First, the cost of an indirect call comes from prediction73.3Second, group objects of the same kind73.4Third, the shape of the code that chooses73.5Devirtualisation — when the compiler removes an indirect call73.6Inline caches and polymorphic inline caches73.7The cost of security mechanisms73.7.1Spectre and retpoline73.7.2Indirect calls that check the type — CFI73.8Which way of choosing to use73.9Summary
74.1People who put a language on top of C74.2A little Objective-C74.3Class records of the 1980s — the X Toolkit Intrinsics74.4GObject — the largest model case74.4.1The order in which the table is built74.5Python’s type objects — CPython74.6Tables in kernels — Linux and FreeBSD74.7COM from C74.8Tables that survive new versions — SQLite and OpenSSL74.9Other ideas — libraries and experiments74.10Papers that measured dispatch74.11Ideas worth noticing in these systems, in one table74.12Summary
75.1Macros — the useful, the cost, the ones to avoid75.1.1Useful macros75.1.2The cost of macros75.1.3Macros to avoid75.2Design principles — reading SOLID in C75.3The limits of object orientation — memory and caches75.4The limits of object orientation — the flow of a program75.5Where things are going now — object orientation is not a cure-all75.5.1The expression problem — what changes more often?75.5.2C’s enum-match75.6Do not get carried away by object orientation75.7Back to the beginning75.8Summary75.9Closing Part XI
Part XII — Reading the standard library
76.1The landscape — the toolboxes76.2Why it is thin — design and history76.3An anatomy of the output format string76.4The input format string — what differs76.5The places to beware
78.1Open, write, close — failure can happen three times78.2How to know the end of a file — the misuse of feof78.3Lines longer than the buffer78.4Text mode and binary mode78.5File position and size
79.1The death of gets and its successors79.2The remaining traps of formatted input79.3The traps on the output side79.4The remaining functions that handle files
80.1The truth about strncpy80.2Then what should be used?80.3Overlapping regions — memcpy and memmove80.4strtok — it destroys the original and hides state80.5The traps of the remaining functions
81.1Conversion — why atoi is abandoned81.2Dynamic allocation — five functions and their contracts81.3Termination — the difference between four ways81.4Sorting and searching — qsort and bsearch81.5Random numbers — the limits of rand81.6The environment and processes
82.1The <ctype.h> functions at a glance82.2The first trap — never pass a char straight in82.3The second trap — EOF is mixed in82.4The judgement depends on the locale82.5It means nothing for multibyte characters
83.1Why it exists — conventions differ by country83.2A locale is process-global state83.3The six categories — what governs what83.4The exact contract of setlocale83.5The grammar of a locale name83.5.1Codeset names and normalisation83.5.2Names in other worlds — BCP 47 and Windows83.6The precedence of the environment variables83.7Where locale data lives
84.1One window — localeconv84.1.1The twenty-four members at a glance84.1.2How the grouping string is encoded84.1.3A monetary form is assembled from three values84.2LC_NUMERIC — where data is quietly corrupted84.3LC_TIME — writing dates and times84.4LC_COLLATE — strcmp is not dictionary order84.4.1strxfrm — why such a function exists84.5Locales and threads84.6Prescriptions
85.1What the standard fixes, and what it does not85.2Five kinds of character constant and string85.3MB_CUR_MAX and MB_LEN_MAX85.4Four layers of conversion function85.4.1Why mbstate_t has to exist85.5mbrtowc — taken apart one step at a time85.5.1A whole string at once — mbsrtowcs
86.1A wchar_t split into two camps86.2The limit of UTF-16 and the surrogate pair86.3Windows — the W functions and their exact encoding86.4Linux and glibc — a four-byte wchar_t that goes mostly unused86.5What the toolkits chose — GTK and Qt86.6Streams have an orientation
87.1The principle — UTF-8 inside, conversion only at the boundary87.2Validation — what to reject even when the shape is right87.3The three layers of “how many characters”, and the fourth87.4Normalisation — the same letter, different bytes87.5Case mapping depends on the language87.6Still alive — the legacy two-byte encodings87.7What does the converting
88.1The properties of NaN and infinity88.2Functions often got wrong88.3Rounding modes and floating-point exceptions — <fenv.h>88.4Type-generic — <tgmath.h>
89.1Three representations of time89.2The traps of struct tm89.3Printing to a string — strftime89.4What C23 added to the clock89.5Time zones and summer time — what the standard does not handle
90.1errno — the price of carrying errors in a global90.2assert — the cheapest way to write a contract as code90.3Signals — see the next chapter90.4Non-local jumps — setjmp/longjmp
91.1Where it came from — a Unix inheritance91.2Two functions — the exact shape91.2.1signal’s arguments and return value91.2.2raise’s argument and return value91.2.3The six signals the standard defines91.3What a handler may do91.3.1What sig_atomic_t really is91.4Handlers and memory — why malloc is not on the list91.5What a signal saves and restores — the register context and errno91.5.1errno is the exception — you must look after it yourself91.6The working pattern — raise a flag and return at once91.7POSIX’s sigaction — filling the standard’s gaps91.7.1Inside struct sigaction91.7.2siginfo_t — who sent it, and why91.7.3Blocking a signal for a while — the mask91.8Real uses91.8.1Graceful shutdown — the most widely used pattern91.8.2SIGPIPE — the signal whose right answer is to ignore it91.8.3Interrupted system calls — EINTR91.8.4Which software uses signals, and why
92.1Why it exists — the makeshift of a language without exceptions92.2setjmp and longjmp — the exact shape92.2.1setjmp — the macro that seems to return twice92.2.2Where setjmp may appear — four contexts only92.2.3longjmp — three things to check before jumping92.3What jmp_buf really is92.3.1Looking inside the eight slots of jmp_buf92.3.2Register restoration is the volatile rule92.4What happens to values on return — the volatile rule92.5Nobody cleans up the resources92.5.1The quieter accident — a pointer reverts to its old value92.6What is actually built on this92.6.1How software built on setjmp copes with memory — the answer is always the same92.7POSIX’s sigsetjmp/siglongjmp92.8Its place today — when to use it, what to use instead
93.1What C99 added93.2What C11 added93.3What C23 added93.4Annex K — the failed attempt at “safe functions”93.5What the library tour leaves behind
94.1Why threads entered the standard94.2The first strand — making one and waiting94.3And then the value comes out wrong94.4Mutual exclusion — mtx_*94.5Waiting — cnd_*94.6Once only — call_once94.7One per strand — thread_local and tss_*94.8★ So why does practice still use pthread?94.9Where to use it and where not to
95.1The lost update — seen with our own eyes95.2Why volatile is not the answer95.3Atomic types and operations95.3.1CAS — “if it is still what I saw, change it”95.4Memory order — not touching it is the default95.4.1Why “order” is a question at all95.4.2The pair builds a wall — release and acquire95.4.3Is ordering free? — measure it95.5The phrase “lock-free”95.6Where to use it and where not to95.7When the holder stops — priority inversion and spinlocks95.7.1The same illness, another face — spinlocks in user space
96.1The trap of checking afterwards96.2C23′s answer — ckd_add, ckd_sub, ckd_mul96.3Where it is used — size calculation comes first96.4Where this tool is absent
97.1What was promoted97.2bool — what does it prevent97.3nullptr — not a renaming97.4The remaining promotions and the new words97.5Attributes — writing down intent the type cannot carry97.5.1What an attribute does — measured97.5.2Unknown attributes are ignored97.6How to move existing code over
98.1Regions in the executable file, regions in the address space98.2Linux’s layout98.3Windows’ layout98.4The world with no operating system — freestanding implementations98.4.1Arm Cortex-M — the first word of the vector table is the stack pointer98.4.2AVR — Harvard architecture, so even constants are copied98.4.3PIC — banks and the “compiled stack”
99.1Ledger ① — the header attached to each block99.2Ledger ② — lists by size and caches per strand99.3Fragmentation — memory grows though there is no leak99.4Swapping out the standard malloc — alternative allocators99.5Freeing with the size — C23′s free_sized99.6Alternative standard libraries99.7Alternatives that change the shape — arenas, pools, and the allocator as an argument
Part XIII — proven — a new, stable foundation
100.1One — string functions do not know the size of the vessel100.2Two — nothing makes you check for failure100.3Three — printf believes exactly what you tell it100.4Four — who frees this100.5Five — a callback nobody can type-check for you100.6And a sixth — bytes have types
101.1Why this library exists101.2What the name says — provenance101.3What it sets out to replace101.4The promises that shaped the design101.5What it is not101.6The choice of having nothing to install101.7How this book’s examples are built101.8The first program101.9Three rules — the key to this whole part101.10The life of one object101.11Attaching it to your own project — a minimal Makefile
102.1Two shapes of return102.1.1Every error code102.1.2The kinds of result bundle102.2Throw it away and the compiler protests102.3What remains after a failure — failure atomicity102.4Raising a failure upward — together with the cleanup102.5When there is nobody to return to — the panic
103.1Bytes have a name103.2Views — pointer and length as one103.3Slicing — the operation used most in this part103.4Size arithmetic that does not overflow103.5Alignment — pushing up to the next boundary
104.1An allocator is a value104.2Swapping the three sources104.3The arena — things of the same lifetime, all at once104.4Which allocator to choose104.5Owning and borrowing, and state that points at itself
105.1Two types, one rule105.2Refuse, rather than truncate105.3Three kinds of writing — refuse, truncate, grow105.4The operations that edit a string105.5Finding and cutting — text handling without copying105.6The boundary of two worlds — NUL termination and UTF-16
106.1{} — the placeholder with no type106.1.1The whole grammar after the colon106.1.2Printing a type the library has never heard of106.2Which formatting function to use106.3The opposite direction — the scanner
107.1The life cycle of the four containers107.2The growing array107.3The intrusive list — linking without allocation107.4The ring buffer — a stream of fixed size107.5The hash map, and data structures under attack107.6Sorting with a worst-case guarantee107.7Bytes into text — hashes and encodings
108.1The life of one file108.1.1The convenience functions that read and write in one go108.2Streams — reading and writing with a buffer108.3Time — two different clocks108.4Random numbers — the purpose decides the generator108.5Memory mapping
109.1Stackless coroutines — overlapping without threads109.2The job system — using several cores109.3Threads, allocators, and provenance109.4When there is no OS — freestanding109.4.1The actual build procedure109.5Where this library stands — what it is, and what it is not109.5.1What has been verified so far109.5.2Stability — what may still change109.5.3What is not there yet109.6When it is better not to use it
110.1What we are building110.2The plain C edition110.3The proven edition110.4One step further — nesting, without recursion110.4.1What was used where110.5So what actually changed
Part XIV — Closing
111.1make — what is to be remade111.2git — what changed and when111.3The rest of the toolbox — building, observing, checking111.3.1① What to make and how — building and dependencies111.3.2② What has gone wrong — debuggers and record-replay111.3.3③ Where is it slow — profilers111.3.4④ Is the code right — checking and testing111.3.5⑤ Is it good for people to read — formatting and documentation111.4What runs in C even today — and why111.5The industry’s rulebooks — MISRA (Motor Industry Software Reliability Association) C and its neighbours111.5.1MISRA C — out of the car industry and into everything111.5.2The neighbours — safety standards and coding rules111.5.3What gets forbidden — a common pattern111.6C and C++ — siblings, not parent and child111.7Put C code into a C++ compiler111.8Time flows faster on the C++ side111.9How to mix them — extern "C"111.10Embedded — C’s home ground111.11How to cross the limits — the knack of practice
112.1What changes when there is a build112.2How files are divided — the header is the contract, the source the circumstances112.3The boundary between public and internal112.4Folder layout — what the conventions are for112.5Kinds of test — what each one catches112.6Golden tests — freezing the answer in a file112.7How much, and what not to test112.8Working together — what the machine refuses and what people look at112.9What has to be written down
113.1Without names, the same thing gets called different things113.2The fixture — the ground a test stands on113.3The witness — a check stood up at every fix113.4The negative check — does that check really bite113.5The ratchet — a number that must not grow113.6Tiers — you cannot always run everything113.7One piece of work — separating decision from execution113.8No silent failures — and the commit is the record of a decision
115.1Retrospect — the C23 already used115.2The practices of modern C — one sheet of guidance115.3The appendices — a bridge beyond this book115.4Books to read next, and the standard document115.5Finally
Front and back matter
The skeletons of a format specificationOutput conversions — the whole listFlags, width, precisionLength modifiers — the place that tells the type’s widthFormats for fixed-width integersInput conversions — the whole listRules that apply only to inputReturn values at a glanceA collection of common mistakes
Integer promotionThe usual arithmetic conversions (the common type of two operands)Default argument promotions in variadic callsInteger conversion rank (the criterion of the conversion rules)Which conversion brings which dangerA list of the places quiet conversions happenOther conversions often met
<string.h> — strings and memoryWorking on blocks of memory (mem*)Copying and joining (strcpy and strcat families)Comparing, and lengthSearching and splittingError strings<ctype.h> — the kinds of a single byte<stdckdint.h> — arithmetic that answers about overflow<assert.h> — checking a contract while it runs<errno.h> — where a failure leaves its reason<setjmp.h> — writing down a place to come back to<stdarg.h> — walking arguments whose number is unknown<stddef.h> — names for the things that had none<stdbool.h> and <stdalign.h> — the two headers that emptied out<iso646.h> and <stdnoreturn.h> — one scar and one retired name<limits.h> — where the integers end<float.h> — where the reals end<stdint.h> — integers with the width nailed down<inttypes.h> — printing and reading those integers<stdbit.h> — counting bits, the standard way<locale.h> — changing whose conventions apply<wctype.h> — the kinds of a wide character<uchar.h> — characters with the Unicode width nailed down<signal.h> — interruption from outside<fenv.h> — reaching into the floating-point environment<tgmath.h> — it picks the one that fits the type<complex.h> — complex numbers<threads.h> — the standard’s own threads<stdatomic.h> — operations that cannot be split<wchar.h> — everything about wide characters<time.h> — instants and durations<stdlib.h> — the drawer of odds and ends<stdio.h> — stream input and output<math.h> — the mathematical functions
The notation for writing grammar — from BNF to EBNFHow to read the C standard’s notationA.1 Lexical grammarA.1.1 Lexical elementsA.1.2 KeywordsA.1.3 IdentifiersA.1.4 Universal character namesA.1.5 ConstantsA.1.6 String literalsA.1.7 PunctuatorsA.1.8 Header namesA.1.9 Preprocessing numbersA.2 Phrase structure grammarA.2.1 ExpressionsA.2.2 DeclarationsA.2.3 StatementsA.2.4 External definitionsA.3 Preprocessing directivesWhat the grammar cannot answerHow to find the grammar in the standard document
What a dump isWhat is in it, and what is notThe shape of the file — a Linux core is an ELFTurning an address into a nameHow the stack is unwoundThe order to read inMaking sure a dump is left — and the common reasons none isWhat to take from this
A word before this appendixWhen the power comes on — a machine running without an OSA list of what the OS was doing for us“An uninitialised global is zero” is not freeThe reset vector — the first place the machine readsWhat to take from thisInterrupts — the mechanism that seizes the flowInterrupt, exception, trap — three words told apart firstYou have met this before — how a hardware exception reaches a C functionPending interrupts do not pile up as a countCan a handler be written in C — the answer differs by chipWhy so little may be done inside a handlerWhat to take from thisTouching device registers — memory-mapped I/O and volatileDevices have addressesA name for it — memory-mapped I/OThe other side — distinguishing I/O by instruction (port-mapped I/O)Which is why volatile existsInterrupts are not the only thing that changes memory behind the program’s back — DMAWhat volatile does not doBriefly disabling interrupts — the oldest lockDo not draw a hardware register as a bit-fieldWhat to take from thisC under constraint, and bringing it backOne timer interrupt, all the way throughHow to live without an allocatorWriting the width into the nameHandling fractions as integers — fixed pointHow deep does the stack goTime and power become visible in the codeBringing it back — reading it again on an OS
Words to know firstFour axes that separate connectionsThe oldest wire — UART and RS-232Frames — cutting characters out of an idle wireRS-232 — the same frame, different voltagesFlow control — how to say “wait”The four errors a UART reportsThe driver — the eight registers of the 16550Why parallel disappearedMany devices on two wires — I2CThe driver — telling a controller one signal at a timeFast on four wires — SPIThe driver — asking a flash chip its nameOn one wire, and with anyone speaking — 1-Wire and CANThe motorway inside the machine — PCI and PCI ExpressConfiguration space — the 256 bytes in which a device introduces itselfThe motorway going out — USBInterruption — IRQsMoving it instead — DMAThe three compared — polling, interrupts and DMAWhat to take from this
Words to know firstA disk is a row of numbered cellsWhy divide at allMBR — everything written into the first 512 bytesThe 16-byte partition entryWhen four partitions are not enough — extended partitions and the EBR chainGPT — rebuilt out of an array, a check and a copyThe protective MBR — sector 0 is still an MBRThe 92-byte GPT headerThe 128-byte GPT partition entryA GUID is written one way and stored anotherAlignment — why exactly sector 2048What is inside a partition — a filesystem’s first sectorFAT32 — the easiest example to readHow a bootloader reads one fileHow ext4 and NTFS differ from FATThe physics of the medium — why random writes are slowThe spinning platter — the time to reach a placeThe semiconductor — writing and erasing in different unitsWhat was measured on this machinefsync — the cost no cache can hideWhat breaks whereWhat to take from this
The four questions a loader asks a fileA format with no header — the DOS .COMMZ — the first header DOS addeda.out — the first Unix format, and its limitCOFF, and its descendant PEELF — two listsOther formats, and magic numbersWhat to take from this
When the power comes onThe BIOS era — 512 bytes was all there wasThe layout of the disk — from MBR to GPTUEFI — the firmware reads a filesystemWhat a bootloader actually doesWhy several stages — the shadow of 446 bytesThe UEFI path — found by name and by variableWithout a bootloader — the Linux EFI stubEmbedded — U-Boot and MCUbootWhat is handed over at the handoverWhen it will not boot — telling links apart by symptomBy operating system — what happens after thatMS-DOSWindowsLinuxRTOSes and small machinesThe chain is a chain of trustWhat to take from this
Why measure — with concepts alone, what remains is wrong intuitionMeasure the measuring instrument first1. The example reads the machine’s numbers itself2 and 3. Resolution and call cost are different things4. The first trap — the optimiser removes what you meant to measure5. The second trap — the first round is slow6. The third trap — one interruption drags the meanThe six disciplines of this appendixMeasuring the memory ladderFirst the principle — why a ladder appearedSo how must it be measuredWhat was measured — the steps appearLines and strides — the unit a cache fetchesFirst the principle — why a line and not a single itemThe method — vary the stride, fix the countWhat was measured — the line appears in the timeThe same data, laid out differently — AoS and SoAAddress translation has a cost too — the TLB and pagesFirst the principle — the translation table and its cacheThe method — little data, many pagesThree things measuredThe cost of a fork in the road — branch predictionFirst the principle — why the machine must guessBefore measuring — is there still a branchWhat was measuredHow regular must it be to be predictedThe cost between cores — false sharing and atomicsFirst the principle — a line belongs to one core at a timeFalse sharing — I slow down because of somebody else’s variableWhat was measuredReally shared values — atomics and locksThe cost of numbers — floating pointFirst, this section’s measurement failed onceMeasured 1 — denormals were 72 times slowerMeasured 2 — is float faster than double?Measured 3 — the operations cost differentlyEverything measured, in one placeMeasured again on real ARM hardwareHow to use these numbersWhat to take from this
Three kinds of machineThe shape of translation — what an MMU actually doesThree consequences of translationOne — an allocation is a promiseTwo — the bill for that promise comes laterThree — the copy that copies nothingUsing the layout, not just obeying itMachines that do not translateWhen there is more than one address spaceCaches, DMA, and scratchpadsPointers are carrying more than an address
Why — what standard C does not give youWhat standard C alone can still finishWhat the gap really is — not a matter of skill in CFour roads — what else must be learnedOne window on the screen — roads to a GUIWhat to buildWhere to learnGoing deeper into CSeeing computer science widelyGuides and lists
Jens Gustedt, Modern C — a textbook built on the standardK. N. King, C Programming: A Modern Approach — the orthodox textbookChristopher Preschern, Fluent C — design and patternsOnline referencesRunning code straight in a browserTools that show youPlaces that hand you problemsWhat can be read for freeAn eye for material — spotting what is out of dateHow to obtain the standard documentThe roads after this book