We can define macros that we can "modify" by passing arguments to them.
However, we do need to take some care in how we define these macros.
Consider the definition:
# define PRODUCT(x,y) x * y;
if we had a use of that macro in a program somewhere like:
a = PRODUCT(b,c) + PRODUCT(d,e);
How would those macros expand?
Consider the definition:
# define PRODUCT(x,y) x * y;
if we had a use of that macro in a program somewhere like:
a = PRODUCT(b,c) + PRODUCT(d,e);
How would those macros expand? We would get:
# define PRODUCT(b,c) x * y;
which would substitute to:
# define PRODUCT(b,c) b * c;
which would substitute to:
a = b * c; + PRODUCT(d,e);
and:
# define PRODUCT(d,e) x * y;
which would substitute to:
# define PRODUCT(d,e) d * e;
which would substitute to:
a = b * c; + d * e;;
So we should
# define PRODUCT(x,y) x * y
we had a statement like:
a = PRODUCT(b+c,d+e);
What would we get?
we had a statement like:
a = PRODUCT(b+c,d+e);
What would we get?
# define PRODUCT(b+c,d+e) x * y
which would substitute to:
# define PRODUCT(b+c,d+e) b+c * d+e
which would substitute to:
a = b+c * d+e;
So we should
# define PRODUCT(x,y) (x) * (y)
to get:
a = (b+c) * (d+e);
we had a statement like:
a = PRODUCT(b,c) / PRODUCT(d,e);
What would we get?
we had a statement like:
a = PRODUCT(b,c) / PRODUCT(d,e);
We would get:
# define PRODUCT(b,c) (x) * (y)
which would substitute to:
# define PRODUCT(b,c) (b) * (c)
which would substitute to:
a = (b) * (c) / PRODUCT(d,e);
and:
# define PRODUCT(d,e) (x) * (y)
which would substitute to:
# define PRODUCT(d,e) (d) * (e)
which would substitute to:
a = (b) * (c) / (d) * (e);
So we should:
# define PRODUCT(x,y) ((x) * (y))
What would we get?
a = ((b) * (c)) / ((d) * (e));
We can see it is always a good idea to put parentheses in the macro definitions to make sure operators get evaluated as we intended no matter how the macro is used.