const, volatile, register, restrict
A deeper pass on const and volatile, plus register and restrict.
A second pass on const/volatile from 1.2.G, plus the two rarer qualifiers that don't come up often but explain some odd-looking code when they do.
volatile earned a second look because the MMIO pattern from 1.2.H is exactly why it exists — without it, the compiler is fully entitled to assume a value it just wrote never changes on its own, cache it in a register, and skip a "redundant" re-read that would actually have picked up a hardware status change.
register int counter; /* a hint, not a promise — the compiler can ignore it */
void process(int *restrict a, int *restrict b) {
/* restrict: a promise to the compiler that a and b never point at
overlapping memory, which unlocks optimizations that would
otherwise be unsafe if they did overlap */
}register asks the compiler to keep a variable in a CPU register instead of memory — in practice compilers make that call themselves now and mostly ignore the hint. restrict is closer to a contract than a hint: it tells the compiler two pointers won't alias each other, which is exactly the kind of thing memcpy relies on (and memmove, from 1.3.F, exists precisely for the case where that promise can't be made).
Notes from readers
Comments — via GitHub