Ответ 1
Возьмем макрос для вычисления максимума двух значений:
#define MAX(a, b) ((a) < (b) ? (a) : (b))
Затем мы используем его следующим образом:
int x = 5;
int y = 10;
int max = MAX(x++, y++);
Затем макрос расширяется до
int max = ((x++) < (y++) ? (x++) : (y++));
Как вы можете видеть, операция приращения на x
или y
будет происходить дважды, а не то, что произойдет, если бы у вас была функция, в которой каждый передаваемый вами аргумент оценивается только один раз.
Еще один важный момент - использование скобок в макросе. Возьмем еще один простой макрос:
#define MUL(a, b) a * b
Теперь, если вы вызываете макрос как
int sum = MUL(x + 3, y - 2);
то разложение становится
int sum = x + 3 * y - 2;
Что из-за приоритета оператора равно
int sum = x + (3 * y) - 2;
Часто не совсем то, что ожидалось, если ожидать (x + 3) * (y - 2)
.
Эта проблема также "решена" с помощью функций.