"If you examine the expansion of max, you will notice some pitfalls. The expressions are evaluated twice; this is bad if they involve side effects like increment operators or input and output. For instance, the below example will increment the larger twice."
I don't see what the problem is with the code above. i is incremented and j is incremented and then it performs a ternary operation to see which is greater. Am I missing something?
Macros are textual substitution, they're basically a copy-paste mechanism.
By the way, did you know that every time you #include something, that entire file just gets copy-pasted into the current one?
So:
1 2 3 4 5
#define max(A, B) ((A) > (B) ? (A) : (B))
max(i++, j++) // after preprocessor expands this macro, it becomes
((i++) > (j++) ? (i++) : (j++))