Problem with Macros

2019-01-15 10:14发布

问题:

HI ,

Can some one help me in understanding why the value of SQUARE(x) is 49 ?

I am using Visual C++ 6.0 .

#define SQUARE(X) X * X

int main(int argc, char* argv[])
{
    int y = 5;

    printf("%d\n",SQUARE(++y));
    return 0;
}

回答1:

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)



回答2:

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?



回答3:

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



回答4:

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.



标签: c++ macros vc6