pitfalls of macro substitution

"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."

1
2
3
#define max(A, B) ((A) > (B) ? (A) : (B))

max(i++, j++)	/* WRONG */


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++))


Here's another example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define MULTILINE_MACRO(x) {\
    function_a(x); \
    function_b(x); \
    function_c(x); \
}

if (x != 0)
    MULTILINE_MACRO(x); // boom
else
    something_else();

// the above if() looks like

if (x != 0)
{
    function_a(x);
    function_b(x);
    function_c(x);
}; // <--- boom
else
    something_else();


Which is why multi-line macros are sometimes written like:

1
2
3
4
5
#define MULTILINE_MACRO(x) do {\
    function_a(x); \
    function_b(x); \
    function_c(x); \
} while (false) 
Topic archived. No new replies allowed.