Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

c - Macros and postincrement

Here's some more weird macro behavior I was hoping somebody could shed light on:

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

void main(void)
{
  int a = 3, b=4;

  printf("%d %d %d
",a,b,MAX(a++,b++));
}

The output is 4 6 5. The value of b is incremented twice but not before MAX displays its value. Can anybody please tell me why this is happening and how does one predict such behavior? (Another instance of why macros should be avoided!)

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Macros do text substitution. Your code is equivalent to:

printf("%d %d %d
",a,b, a++ > b++ ? a++ : b++);

This has undefined behavior, because b is potentially incremented (at the end of the third argument) and then used (in the second argument) without an intervening sequence point.

But as with any UB, if you stare at it for a while you might be able to come up with an explanation of what your implementation has actually done to yield the result you see. Order of evaluation of arguments is unspecified, but it looks to me as though the arguments have been evaluated in right-to-left order. So first, a and b are incremented once. a is not greater than b, so b is incremented again and the result of the conditional expression is 5 (that is to say, b after the first increment and before the second).

This behavior is not reliable - another implementation or the same implementation on another day might give different results due to evaluating the arguments in a different order, or theoretically might even crash because of the sequence point issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...