为什么'max'宏在C中定义如下?

时间:2011-03-16 10:09:51

标签: c macros

 #define max(a,b) \
   ({ typeof (a) _a = (a); \
       typeof (b) _b = (b); \
     _a > _b ? _a : _b; })

为什么不简单地(a>b ? a : b)

4 个答案:

答案 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++);

在这种情况下,使用更简单的版本,最大值会增加两倍。