C preprocessor macros can be used with great benefits; but you have to know how to write them, or you can run into unexpected problems. For example, let's look at the following innocent-looking #define:
/* WRONG! */
#define SQUARE(x) x * x
Does it work? Most of the time. But when someone (not necessarily the author of the macro) attempts to calculate SQUARE(3 - 1), he or she gets -1. Surprising, isn't it? The problem is especially hard to trace if the macro call is hidden in a large expression.
These problems arise because C macros are expanded at the preprocessor level, and all syntax and semantic analysis is done after this stage. Preproccesor simply replaces SQUARE(3 - 1) with 3 - 1 * 3 - 1, which is, of course, parsed as 3 - (1*3) - 1 and evaluated to -1. This bug can be fixed by puting parentheses around all references to arguments in a macro definition; but that still leaves some problems unsolved. Let's look at a bit different macro:
/* STILL WRONG! */
#define DOUBLE(x) (x) + (x)
Again, this works sometimes and misteriously gives incorrect results in other expressions. For example, DOUBLE(2)*10 gives an unexpected result, because precedence of multiplication is higher than that of addition. This can be fixed by enclosing the macro body in parentheses:
/* Sort of right, but see below.. */
#define DOUBLE(x) ((x) + (x))
This is the best we can do as far as preprocessor macros go. But there are still pitfalls: x is evaluated twice, so if an argument to a macro has any side effects (for example, ++ or --, or a call to a function), then again the Wrong Things will happen. This can't be avoided, and therefore this behaviour is officially declared a Feature. BTW, the convention to use upper case letters for macro names is a good thing because it alerts the programmer to potential problems.
Morale: write macros defensively, puting parentheses around arguments and macro body; do not pass expressions with side effects to macros; use alternatives (such as inline functions) whenever possible.