Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
522 views
in Technique[技术] by (71.8m points)

c - What are expressions with side effects and why should they be not passed to a macro?

I came across a statement in the text C How to Program:

"Expressions with side effects (i.e., variable values are modified) should not be passed to a macro because macro arguments may be evaluated more than once.".

My question is what are expressions with side effects and why should they be not passed to a macro?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The classic example is a macro to calculate the maximum of two value:

#define MAX(a, b) ((a) > (b) ? (a) : (b))

Now lets "call" the macro like this:

int x = 5;
int y = 7;
int z = MAX(x++, y++);

Now if MAX was a normal function, we would expect that x and y would be incremented once, right? However because it's a macro the "call" is replaced like this:

int z = ((x++) > (y++) ? (x++) : (y++));

As you see, the variable y will be incremented twice, once in the condition and once as the end-result of the ternary operator.

This is the result of an expression with side-effects (the post-increment expression) and a macro expansion.


On a related note, there are also other dangers with macros. For example lets take this simple macro:

#define MUL_BY_TWO(x)  (x * 2)

Looks simple right? But now what if we use it like this:

int result = MUL_BY_TWO(a + b);

That will expand like

int result = (a + b * 2);

And as you hopefully knows multiplication have higher precedence than addition, so the expression a + b * 2 is equivalent to a + (b * 2), probably not what was intended by the macro writer. That is why arguments to macros should be put inside their own parentheses:

#define MUL_BY_TWO(x)  ((x) * 2)

Then the expansion will be

int result = ((a + b) * 2);

which is probably correct.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...