Sean
You have a good suggestion to make these macros. They seem to work to perfection, however, there is a common error that you made.
When writing macros, it is a good idea to surround your arguments with parenthesis in the definition.
Let's walk through this example
Code:
#define PI 3.14
#define CIRCLE_AREA(r) (PI * (r) * (r))
area = CIRCLE_AREA(4)
expands to
Code:
area = 3.14 * (4) * (4)
Often times, though, you may have an expression that you're passing to the macro
Code:
area = CIRCLE_AREA(i+2)
which would expand to
Code:
area = 3.14 * (i+2) * (i+2)
Now let's see what happens when we remove the parenthesis in the macro
Code:
#define CIRCLE_AREA(r) (PI * r * r)
area = CIRCLE_AREA(i+2)
expands to
Code:
area = 3.14 * i + 2 * i + 2
The order of operations that C follows causes the result to be clearly different from what you would have expected. It would evaluate as if it were grouped like this
Code:
area = (3.14 * i) + (2 * i) + 2
The moral of the story is that the parenthesis around parameters in the macro definition to make it more portable. If I see a macro that calculates the area of a circle, I don't want to have to double check it to see how the order of operations will play out. Same goes for the parenthesis around the entire expression. For the most part, you will have no problems, but it never hurts to be safe.
On a side note, I try to use functions instead of macros when efficiency is less critical or when the routine to be run is complex.
Now, I don't want to get into a whole debate about macros and functions, because each has their place. I find that it is easier to debug functions than macros because you can step through them in a debugger.