宏的问题

Suj*_*osh 5 c++ macros visual-c++-6

嗨,

有人可以帮助我理解为什么SQUARE(x)的值是49?

我使用的是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;
}
Run Code Online (Sandbox Code Playgroud)

moa*_*ala 16

Neil Butterworth,Mark和Pavel是对的.

SQUARE(++ y)扩展为++ y*++ y,它增加了y值的两倍.

您可能遇到的另一个问题:SQUARE(a + b)扩展为a + b*a + b,它不是(a + b)*(a + b)而是a +(b*a)+ b.在定义宏时,您应该在需要时在元素周围添加括号:#define SQUARE(X)((X)*(X))风险稍低.(Ian Kemp在他的评论中首先写了这篇文章)

您可以改为使用内联模板函数(在运行时效率不低),如下所示:

template <class T>
inline T square(T value)
{
    return value*value;
}
Run Code Online (Sandbox Code Playgroud)

你可以检查它的工作原理:

int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
Run Code Online (Sandbox Code Playgroud)

(不需要写

square<int>(++i)
Run Code Online (Sandbox Code Playgroud)

因为int类型是隐含的i)

  • 但是要清楚 - ((++ y)*(++ y))根据程序文本中的内容增加"y"两次,但是会导致未定义的行为,这意味着当程序运行'y'时可能会增加一次,两次,三次,从不,或程序可能会崩溃.你只是不知道会发生什么. (3认同)

小智 15

因为宏扩展到:

++y * ++y
Run Code Online (Sandbox Code Playgroud)

它在C++中给出了未定义的行为 - 结果可能是任何东西.任何涵盖宏使用的体面教科书都应该涵盖这个众所周知的问题.你在用哪一个?


use*_*019 5

因为宏会进行文本替换,所以您编写的代码会扩展为

printf("%d\n",++y * ++y );
Run Code Online (Sandbox Code Playgroud)

然后操作的顺序是未定义的行为,因此编译器看到2个增量,然后是乘法

所以要小心使用宏来使用函数,因为编译器可以内联扩展不再需要运行.

其次,不要假设如果增量和使用变量会发生什么


P S*_*ved 5

宏不是函数:它们只是改变程序的文本.此操作称为预处理,它在代码编译之前自动执行.人们编写宏来节省时间并为源代码引入一些可变性.

当你写SQUARE(x),没有实际的函数调用发生,只是文本被修改.操作非常愚蠢,所以你必须在像你这样的情况下采取额外的预防措施.有关您的案例的解释,请参阅其他答案.