【发布时间】:2013-08-02 13:19:56
【问题描述】:
#define MIN (A,B) ((A)<(B)?(A):(B)) 或 #define MIN (A,B) ((A < B)? A : B )
请选择一个答案,为什么?!
【问题讨论】:
-
请不要使用。不止一次评估参数的宏是危险的。现代 C 具有类型通用表达式,可以帮助为工作选择正确的内联函数。
标签: c macros c-preprocessor
#define MIN (A,B) ((A)<(B)?(A):(B)) 或 #define MIN (A,B) ((A < B)? A : B )
请选择一个答案,为什么?!
【问题讨论】:
标签: c macros c-preprocessor
让我们有这个表达式:
int c = MIN(x == y, 1);
让我们试试#define MIN (A,B) ((A < B) ? A : B )
在 C 中,== 运算符的优先级低于<(所以x == y < z 等同于x == (y < z)),所以它会变成
int c = MIN (x == (y < 1) ? x == y : 1)
如果你使用第二种表达方式...而且是错误的,所以最好使用第一种形式。
让我们试试#define MIN (A,B) ((A) < (B) ? (A) : (B)) 以确保...
我们来了
int c = MIN ((x == y) < (1) ? (x == y) : (1))
好多了!
最后他们都是“坏的”,因为
int c = MIN(++x, 1);
将对++x 进行两次评估(一次在< 比较中,一次如果它被三元运算符“选择”作为结果)
int c = MIN ((++x) < (1) ? (++x) : (1))
【讨论】:
就我个人而言,我不会使用任何一个,因为像 MIN(++a, ++b) 这样的表达式可能会让你搞砸(由于双重评估)。
【讨论】:
a++ < b++ 是未定义的行为。
a++ < ++a 感到困惑,这最终确实会发生。
我个人的偏好是:
inline int min(int a, int b)
{
return (a > b)?b:a;
}
这样更安全,不需要额外的括号,并且如果您执行以下操作也不会“爆炸”:
x = min(x++, y++);
【讨论】:
while(*ptr) lowest = min(*ptr++, lowest); 或类似的东西——如果它是一个宏,它的行为也会很奇怪。
前者,因为 A 或 B 可以是嵌套命令。考虑这两个宏如何扩展它:
int i = MIN(3+1,2);
【讨论】:
int i = MIN(6, a++) 扩展为int a = 10。