【问题标题】:MAX using typeof extension of gccMAX 使用 gcc 的 typeof 扩展
【发布时间】:2013-06-11 08:11:17
【问题描述】:

我已经用 C 编程了很长一段时间了。所以我决定学习一些高级 C。我听说过 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; })

【问题讨论】:

标签: c gcc macros


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 只有 gcc 吗? typeof ?
  • @GrijeshChauhan,是的,它是 GCC 扩展
【解决方案2】:

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

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));

因为参数只计算一次。

【讨论】:

    【解决方案3】:
    typeof (a) _a = (a);            \
    typeof (b) _b = (b);            \
    

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

    More info

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

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

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

    static inline max (int a, int b)
    {
            if (a > b)
                    return a;
            return b;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-10-19
      • 2013-01-18
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多