C/C++のプログラムにおける、不注意に関数マクロを使うことによって引き起こされる問題はよく指摘されていることです。
Cの生みの親の一人であるカーニハン自身もその著書「プログラミング作法」の中で「関数マクロは使わない方がいい」といっています。
「自分は、この問題をちゃんと理解していて注意しているからいい。」というかもしれませんが、使わなければ注意する必要もありません。
ここで、もう一度関数マクロを使う場合の注意点を整理してその問題を理解し、関数マクロは使わない主義者に加わって欲しいと思います。
#define square(a) ((a) * (a))
y = square(x++);
y = ((x++) * (x++));
#define isupper(a) ((a) >= 'A' && (a) <= 'Z')
if ( isupper(c = getchar()) ) ...
if ( ((c = getchar()) >= 'A' && (c = getchar()) <= 'Z') ) ...
#define square (a) ((a) * (a))
y = square(x++);
y = (a) ((a) * (a))(x++);
#define square(a) (a * a)
z = square(x + y);
z = (x + y * x + y);
#define square(a) ((a) * (a))
z = ((x + y) * (x + y));
#define double(a) (a) + (a)
y = double(x) * 2;
y = (x) + (x) * 2;
#define double(a) ((a) + (a))
y = ((x) + (x)) * 2;
#define release(a) free(a); \
(a) = NULL;
if ( x == 0 ) release(p);
if ( x == 0 ) free(p);
(p) = NULL;
#define release(a) { free(a); \
(a) = NULL; }
if ( x == 0 ) { free(p);
(p) = NULL; }