#define SQR(x) x*x. Unexpected Answer

前端 未结 4 784
半阙折子戏
半阙折子戏 2020-12-12 07:34

Why this macro gives output 144, instead of 121?

#include
#define SQR(x) x*x

int main()
{
    int p=10;
    std::cout<         


        
4条回答
  •  悲哀的现实
    2020-12-12 08:28

    This is a pitfall of preprocessor macros. The problem is that the expression ++p is used twice, because the preprocessor simply replaces the macro "call" with the body pretty much verbatim.

    So what the compiler sees after the macro expansion is

    std::cout<<++p*++p;
    

    Depending on the macro, you can also get problems with operator precedence if you are not careful with placing parentheses where needed.

    Take for example a macro such as

    // Macro to shift `a` by `b` bits
    #define SHIFT(a, b)  a << b
    
    ...
    
    std::cout << SHIFT(1, 4);
    

    This would result in the code

    std::cout << 1 << 4;
    

    which may not be what was wanted or expected.


    If you want to avoid this, then use inline functions instead:

    inline int sqr(const int x)
    {
        return x * x;
    }
    

    This has two things going for it: The first is that the expression ++p will only be evaluated once. The other thing is that now you can't pass anything other than int values to the function. With the preprocessor macro you could "call" it like SQR("A") and the preprocessor would not care while you instead get (sometimes) cryptical errors from the compiler.

    Also, being marked inline, the compiler may skip the actual function call completely and put the (correct) x*x directly in the place of the call, thereby making it as "optimized" as the macro expansion.

提交回复
热议问题