Turns out the preprocessor is actually an organically grown pseudo language (as opposed to a properly designed language feature) inside C, which later got standardized through an incredibly complex set of rules and definitions.
An impressive application of the C preprocessor is the Boost.Preprocessor library [1]. It basically implements a primitive (and bounded) version of Lisp inside the preprocessor.
I used it once to write DSLs to define data structures, where a few lines of code were expanded to hundreds of lines of templates, (de)serialization code, etc...
This can be used to explain much of C. :)