4

我已经用 C 编程了很长一段时间了。所以我决定学习一些高级 CI 听说过 gcc 编译器扩展。下面我看到了 MAX() 的代码,我到目前为止已经实现如下

#define MAX(x,y) ((x) > (y)? (x): (y))

这是我找到的新定义。不幸的是,我什至无法理解以下代码的作用?为什么我会按照下面而不是上面那样做?

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

3 回答 3

8

优点是它避免了像经典宏一样多次评估参数。

通过引入局部变量(使用typeof“克隆”参数的类型),实际表达式只计算一次,然后返回值只是使用局部变量而不是再次计算输入表达式,就像经典宏必须做的那样.

比较如果这样调用会发生什么:

int a = 0, b = 1;
const int c = MAX(++a, ++b);

在第一种情况下,由于输入表达式有副作用,结果将难以预测。在第二种情况下,参数只被评估一次,所以一切都表现得好像MAX()是一个常规函数。

此外,您的第一个宏示例未能将参数括在括号中,这是危险的。

于 2013-06-11T08:13:24.210 回答
3

这是一个通用宏的示例,它适用于不同的数据类型,例如 int 或 float。例如:

int i = 10;
int j = 20;
int k = MAX(i, j);

扩展为:

int i = 10;
int j = 20;
int k = ({ int _a = (i); int _b = (j); _a > _b ? _a : _b; });

然而:

float x = 10.0f;
float y = 20.0f;
float z = MAX(x, y);

扩展为:

float x = 10.0f;
float y = 20.0f;
float z = ({ float _a = (x); float _b = (y); _a > _b ? _a : _b; });

它甚至可以处理混合数据类型,例如

int i = 10;
float y = 20.0f;
float z = MAX(i, y);

除了支持不同的数据类型,它还避免了简单宏的不良副作用,例如

#define MAX(a, b) (((a) > (b)) ? (a) : (b)))

如果您将其调用为例如

int k = MAX(i++, j++);

此外,如果您将表达式作为参数传递,它会更有效,例如

float x = 10.0f;
float y = 20.0f;

float z = MAX(sin(x), sin(y));

因为参数只评估一次。

于 2013-06-11T08:14:45.107 回答
3
typeof (a) _a = (a);            \
typeof (b) _b = (b);            \

创建两个具有相同类型a和的变量b以避免计算两次

更多信息

内联函数最明显的候选者是预处理器宏。GCC 中的内联函数将与宏一样执行,此外,还接受类型检查。例如,代替这个宏:

#define max(a,b) ({ a > b ? a : b; })

可能会使用相应的内联函数:

static inline max (int a, int b)
{
        if (a > b)
                return a;
        return b;
}
于 2013-06-11T08:20:06.493 回答