Because otherwise you'd have a source code that looks like this:
void do_add (bigint_stack &stack) {
bigint right = stack.front();
stack.pop_front();
TRACE ('+', "right = " << right);
bigint left = stack.front();
stack.pop_front();
TRACE ('+', "left = " << left);
bigint result = left + (right);
TRACE ('+', "result = " << result);
stack.push_front (result);
}
void do_subtract (bigint_stack &stack) {
bigint right = stack.front();
stack.pop_front();
TRACE ('-', "right = " << right);
bigint left = stack.front();
stack.pop_front();
TRACE ('-', "left = " << left);
bigint result = left - (right);
TRACE ('-', "result = " << result);
stack.push_front (result);
}
Etcetera...
Now, if you want to add another TRACE, for example, you'd have to again copy-paste it to all of them.
What the author wanted, really, is to define a way to generate functions from a set of parameterized inputs, in such a way that the resulting functions are all similar but they behave in slightly different ways depending on the input given to generate them. It's called meta-programming. Very common in coding parsers, which I suspect is where this snippet came from.
Now, in other languages, a construct specific to that language might exist to do meta-programming like this in a cleaner way (templates, metaclass, etc). But for C, macro is it.