The preprocessor included with C compilers is a strange beast. By far its most common use is to #include
various header files, and to #define
static variables for later use. But there's other, lesser-used features...
The #define
macro takes two forms: either #define X Y
, for a simple find-and-replace; or #define f(X) Y
, where Y is some expression involving X.
For example, the following code:
#define F(X) X X X
F(cheese)
would end up looking like this:
cheese cheese cheese
Staggeringly useful already. But wait: there's one more feature! It's called Token Pasting, and it allows you to "stick" together things that wouldn't ordinarily be tokenizable, like parts of a function name:
#define F(X) void X##AndRice(){}
F(cheese)
is transformed into the following:
void cheeseAndRice(){}
Now, here's some strange-looking C code, which compiles perfectly:
int main(int argc, char **argv) {
float vals[] = {1.1, 2.2, 3.3, 4.4, 5.5};
array(float) nums = new_array(float)(5, vals);
printArray(float)(nums);
}
and prints the following:
1.1
2.2
3.3
4.4
5.5
Instead of leaving vals
as an array on the stack, the templateized code now means that nums
points to an "array" structure on the heap. So how on earth does this work?!