Статья: Макросы в C++
Чтобы увидеть, чем они опасны, попробуйте провести расширения в следующем примере:
int xx = 0; // глобальный счетчик
void f() {
int xx = 0; // локальная переменная
xx = SQUARE(xx+2); // xx = xx+2*xx+2
INCR_xx; // увеличивает локальный xx
if (a-DISP==b) { // a-= 4==b
// ...
}
}
Если вы вынуждены использовать макрос, при ссылке на глобальные имена используйте операцию разрешения области видимости :: и заключайте вхождения имени параметра макроса в скобки везде, где это возможно (см. MIN выше).
Обратите внимание на различие результатов расширения этих двух макросов:
#define m1(a) something(a) // глубокомысленный комментарий
#define m2(a) something(a) /* глубокомысленный комментарий */
например,
int a = m1(1)+2;
int b = m2(1)+2;
pасширяется в
int a = something(1) // глубокомысленный комментарий+2;
int b = something(1) /* глубокомысленный комментарий */+2;
С помощью макросов вы можете разработать свой собственный язык. Скорее всего, для всех остальных он будет непостижим. Кроме того, C препроцессор - очень простой макропроцессор. Когда вы попытаетесь сделать что-либо нетривиальное, вы, вероятно, обнаружите, что сделать это либо невозможно, либо чрезвычайно трудно.