#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
为什么不简单地(a>b ? a : b)
?
答案 0 :(得分:19)
因为其他人max(f(1), f(2))
会两次调用两个函数中的一个:
f(1) > f(2) ? f(1) : f(2)
而是通过“缓存”_a
和_b
中的两个值
({
sometype _a = (a);
sometype _b = (b);
_a > _b ? _a : _b;
})
(显然正如其他人所指出的那样,自动增量/自动减量存在同样的问题)
我认为Visual Studio不支持这种方式。这是一个复合语句。阅读does msvc have analog of gcc's ({ })
我将补充一点,这里给出的gcc手册中复合语句的定义http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC62显示的代码非常类似于max的问题: - )
答案 1 :(得分:8)
它正在解决诸如
之类的主要问题#define max(a,b) ((a) > (b) ? a : b)
当你用:
打电话时int x = max (a++, b--);
由于它是简单的文本替换,因此导致:
int x = ((a++) > (b--) ? a++ : b--);
不你想要的东西。
使用:
#define max(a,b) ({
typeof (a) _a = (a);\
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
它使用临时变量,有效地为您提供:
int x = ({ int _a = a++; int _b = b--; _a > _b ? _a : _b; })
仅运行副作用一次。
但是,说实话,你应该完全抛弃那个宏并使用inline
函数,甚至是非内联函数,因为大多数时候,编译器可以做一个不错的优化工作,甚至< em>没有那个建议。
答案 2 :(得分:3)
确定最大值的另一种方法(至少对于正数)
#define MAX(a,b) sizeof(union x { char ca[a]; char cb[b];})
由于a和b只被访问一次,MAX(a ++,b ++)给出了正确的结果。
答案 3 :(得分:1)
如果使用表达式调用宏,则可能会导致意外行为。假设:
int c = max(i++, j++);
在这种情况下,使用更简单的版本,最大值会增加两倍。