c++ - 如何正确扩展这个宏?

标签 c++ c macros

当我定义这个宏时:

#define SQR(x) x*x

假设这个表达式:

SQR(a+b)

这个表达式将被宏替换,看起来像:

a+b*a+b

但是,如果我在表达式前放置一个 ++ 运算符:

++SQR(a+b)

现在的表情是什么样的?这个 ++ 是否放在 SQR 参数的每个部分之前?像这样:

++a+b*++a+b

这里我给出一个简单的程序:

#define SQR(x) x*x
int a, k = 3;
a = SQR(k+1) // 7
a = ++SQR(k+1) //9

最佳答案

当定义宏时,您基本上总是希望将宏参数放在括号中以防止第一个示例中的那种奇怪行为,并将结果放在括号中以便可以安全地使用它而无需副作用。使用

#define SQR(x) ((x)*(x))

使 SQR(a+b) 扩展为 ((a+b)*(a+b)) 这在数学上是正确的(不同于 a +b*a+b,等于 ab+a+b)。

在宏之前或之后放置的东西不会进入宏。所以 ++SQR(x) 在你的例子中变成了 ++x*x

注意以下几点:

int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
           // since preincrement will affect the value of a before it is read.

你看到 ++SQR(a+b) 似乎增加了 2,因为预增量在 a 之前开始,我每次都读过,即 a 递增,然后使用两次,因此结果比预期高 2。

注意 正如@JonathanLeffler 指出的那样,后一个调用会调用未定义的行为;评估不能保证从左到右发生。它可能会在不同的编译器/操作系统上产生不同的结果,因此永远不要依赖它。

关于c++ - 如何正确扩展这个宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12506058/

相关文章:

c - 绑定(bind)到特定地址但随机端口 Linux

asynchronous - 如何以及何时在 Julia 中使用 @async 和 @sync

必须仅包含在调试版本中的源文件的条件编译

c++ - 销毁具有全局实例的类中的静态成员

c++ - 从文件中读取整数到 C++ 中的 vector

给数组元素赋值时,C下标值既不是数组也不是指针也不是 vector

c++ - 如何在 C 宏中连接变量字符串和文字字符串?

c++ - 验证字符串是否只有数字且只有一定长度

c++ - xAudio MasterVoice 取得进展

c - 反转字符串 - 循环不执行