Это чтобы справиться с недостатками макросов - они являются просто заменой текста!
представьте себе следующий макрос
#define DOUBLE(x) x*2
int v = DOUBLE(1+1); // == 1+1*2 == 3. Did you expect 4?
Итак, эмпирические правила для макросов таковы:
- используйте их, только если нет другого способа решения вашей проблемы
- оберните каждый параметр в парантезы (чтобы избежать вышеуказанной проблемы)
- оберните все выражение в парантезы (чтобы избежать других, похожие проблемы)
- заставляет каждый параметр встречаться только один раз (чтобы избежать проблем с побочными эффектами)
Итак, лучший макрос будет:
# define DOUBLE(x) ((x) * 2)
Вы почти на месте, оставшиеся паратезы в вашем примере связаны с исполнением.
Таким образом, мы можем критиковать два момента:
Q: Почему это макрос, а не встроенная функция?
A: Обратная совместимость.В C нет встроенных функций (или, по крайней мере, их нет), использование функций для, вероятно, тысяч таких объявлений привело бы к сбою большинства компиляторов того времени.
Q: действительно ли нужны парантезы для этого конкретного макроса? A: Я не знаю.Вероятно, мне понадобится полчаса или больше, чтобы формально доказать (или опровергнуть) отсутствие разумного параметра и среды «вызова», где это имеет непреднамеренные последствия.Я предпочел бы следовать разумным рекомендациям, как упомянуто выше, и продолжать кодировать.