Problem with Macros

Neil Butterworth, Mark and Pavel are right.

SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.

Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)

You could instead use an inline template function (no less efficient at runtime) like this one:

template <class T>
inline T square(T value)
{
    return value*value;
}

You can check it works:

int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;

(no need to write

square<int>(++i)

because the int type is implicit for i)


Because the macro expands to:

++y * ++y

which gives undefined behaviour in C++ - the result could be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?


Because macros do textual substitution so the code you wrote gets expanded to

printf("%d\n",++y * ++y );

and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication

So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.

Secondly don't assume what will happen if you increment and use variables


Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.

When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.