As this hasn't been downvoted or closed as a duplicate, I'll try and explain
Let's look at your printf
call:
printf("result> %d, %d\n", MIN(b+c, f(3)), MIN_fix(b+c, f(3)));
Now b+c
is effectively a constant value (4), so this turns into
printf("result> %d, %d\n", MIN(4, f(3)), MIN_fix(4, f(3)));
If we expand the MIN
macro invokation, and remove unneeded parens, we get the following
printf("result> %d, %d\n", 4 < f(3)? 4 : f(3), MIN_fix(4, f(3)));
So we have 3 calls to f(3)
in this line of code. The first three calls to that function return 2, 8, and 14 respectively. But there's no guarantee in which order those calls will be evaluated.
Let's let f1=2, f2=8, and f3=14. Your printf could be any of the following with their output in the comment
printf(..., 4<f1?4:f2, MIN_fix(4,f3)); // 8, 4
printf(..., 4<f1?4:f3, MIN_fix(4,f2)); // 14, 4
printf(..., 4<f2?4:f1, MIN_fix(4,f3)); // 4, 4
printf(..., 4<f2?4:f3, MIN_fix(4,f1)); // 4, 2
printf(..., 4<f3?4:f1, MIN_fix(4,f3)); // 4, 4
printf(..., 4<f3?4:f2, MIN_fix(4,f1)); // 4, 2
Any of the outputs are valid - because you have undefined behavior