Preprocessor
Macro Pitfall
Missing parentheses in a macro can change expression precedence.
text substitution
A macro expands as text, so operator precedence still matters afterward.
safer macro
Wrap parameters and the full replacement expression in parentheses.
direct comparison
The replay compares the expanded bad and good expressions directly.
Macro Pitfall
macro_pitfall.c
Replay: real traced execution (multi-file project)
#include <stdio.h>
#define BAD_TRIPLE(n) n * 3
#define GOOD_TRIPLE(n) ((n) * 3)
int main(void) {
int value = 2;
int bad = value + 1 * 3;
int good = ((value + 1) * 3);
printf("bad=%d good=%d\n", bad, good);
return 0;
}
#include <stdio.h>
#define BAD_TRIPLE(n) n * 3
#define GOOD_TRIPLE(n) ((n) * 3)
int main(void) {
int value = 4;
int bad = value + 1 * 3;
int good = ((value + 1) * 3);
printf("bad=%d good=%d\n", bad, good);
return 0;
}
#include <stdio.h>
#define BAD_TRIPLE(n) n * 3
#define GOOD_TRIPLE(n) ((n) * 3)
int main(void) {
int value = 5;
int bad = value + 1 * 3;
int good = ((value + 1) * 3);
printf("bad=%d good=%d\n", bad, good);
return 0;
}
value ← 2, bad ← 5, good ← 9
6int main(void) {7 int value→ 2 = 2; //@value=4, 58 int bad→ 5 = value2 + 1 * 3;9 int good→ 9 = ((value2 + 1) * 3);1011 printf("bad=%d good=%d\n", bad5, good9);12 return 0;13}outputbad=5 good=9
value ← 4, bad ← 7, good ← 15
6int main(void) {7 int value→ 4 = 4;8 int bad→ 7 = value4 + 1 * 3;9 int good→ 15 = ((value4 + 1) * 3);1011 printf("bad=%d good=%d\n", bad7, good15);12 return 0;13}outputbad=7 good=15
value ← 5, bad ← 8, good ← 18
6int main(void) {7 int value→ 5 = 5;8 int bad→ 8 = value5 + 1 * 3;9 int good→ 18 = ((value5 + 1) * 3);1011 printf("bad=%d good=%d\n", bad8, good18);12 return 0;13}outputbad=8 good=18