具有运算符优先级的宏功能是否显示异常结果?

Tau*_*fiq 0 c bitwise-operators

#define SQUARE(x,y) (x<y?x:y)
   int a = 5, b = 6, c = 3;
    int var = SQUARE(a & c,b);
Run Code Online (Sandbox Code Playgroud)

我搜索并了解到'''在'&'之前.根据规则它应该给'5'.但它输出为'1'.但在某些情况下,它会提供正确的输出.你能解释一下宏观规则以及我在这里缺少什么.

Osi*_*ris 5

宏只是由预处理器替换,因此参数不会被评估,然后像函数一样传递.

在您的示例中,表达式SQUARE(a & c, b);将成为(a & c < b ? a & c : b);

因为a=5, b=6, c=3它评估为:

(5 & 3<6 ? 5&3 : 6) //'<' precede '&' as you correctly mentioned
(5&1 ? 5&3 : 6) // '3 < 6' is a boolean expression which evaluates to 1. '&' is bitwise AND.
(1 ? 1 : 6)
(1)
Run Code Online (Sandbox Code Playgroud)

1正确的输出也是如此.

编辑:

一个好的方法是总是在你的参数和整个表达式周围使用括号来消除运算符优先级的问题.

正如其他人所提到的,由于多次评估而使用宏会很危险,这可能不仅会影响性能.

例如:

#define SQUARE(x) ((x)*(x))
Run Code Online (Sandbox Code Playgroud)

似乎只是对论证的方方面面,但如果你称之为

f = SQUARE(x++);
Run Code Online (Sandbox Code Playgroud)

你会得到未定义的行为.小功能的更好方法是将其声明为inline.

inline int square(int x)
{
    return x*x;
}
Run Code Online (Sandbox Code Playgroud)

同样由@EricPostpischil提到的宏不是文本替换,因为预处理器替换为令牌.

例如:

#define a 1
#define b 2

printf("%d\n", ab);
Run Code Online (Sandbox Code Playgroud)

这里ab没有替换12为有人期望的纯文本替换.