Прочитайте wikipage о C preprocessor и поймите, что препроцессор C работает на чисто текстовом уровне (в качестве первой фазы компилятора). Читайте также документацию GNU cpp. Ваш y = SQR(++x);
расширяется в
y = ++x * ++x;
Который не то, что вы должны хотеть. Читайте о undefined behavior (и this answer). Подумайте об ужасах, происходящих (используя ваш оригинал SQR
) с SQR(y+3)
.
Посмотрите на предварительно обработанную форму исходного кода. С GCC, используйте
gcc -C -E foo.c > foo.i
получить в foo.i
(который вы должны изучить с помощью редактора или пейджера) в препроцессоре виде foo.c
Так, по крайней мере, вы должны определить макрос, как
#define SQR(x) ((x)*(x))
В противном случае SQR(y+3)
не будет расширяться, как вы хотите. В общем, при использовании макроса вы должны знать (и документировать, например, в комментарии, если вы пишете макрос), что происходит.
В самом деле, в вашем случае, вы не должны использовать макрос на всех, но определим inline function
static inline int square(int x) { return x*x; }
это будет так быстро, как макрос, но гораздо более безопасным, так как square(++x)
прирост будет (правильно) x
только один раз, и square(y+3)
делает, что вы хотите!
Подумайте, как работают макросы и сколько раз вычисляется выражение. –
@Matt: нет, это не определено как таковое. – usr2564301
@Jongware да это –