GNU C语言的 扩展(一)语句表达式

GNU CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。这里对支持支持 GNU 扩展的 C 语言成为 GNU C。 在 Linux 内核中使用了大量的 GNU C 扩展,以致 GNU C 成为了内核唯一的编译器。



  语句表达式

GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本只能在复合语句中使用。例如有如下宏定义:
引用
#define min_t(type, x, y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })

而标准的宏定义为:
引用
#define min(x,y) ((x) < (y) ? (x) : (y))

这个定义计算 x 和 y 分别两次,当参数有副作用时,将产生不正确的结果,见:http://www.groad.net/bbs/read.php?tid=1034


修改上面链接代码如下
引用
#include <stdio.h>

#define MIN(type, x, y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y;})
int main ()
{
    int i = 10;
    int a[5]={8,9,11,10,13};

    int *p = a;
    int j;
   
    j = MIN(int,*p++,i);
    printf("%d\n",j);
   
    printf("%d\n",*p);

    return (0);
}

运行及输出
引用
beyes@linux-beyes:~/C/micro> ./micro2.exe
8
9

说明
这时候,*P 不再做 2 次的 + 1 运算。这是因为宏定义的语句表达式中有赋值语句,此后作用的是 __x (为 8)而不是 x (为 *p++)。

上面的宏定义,需要提供参数类型,如 int 。但是如果用 typeof  就可以定义更加通用的宏。

测试代码
引用
#include <stdio.h>

#define MIN(x, y) ({ const typeof(x) _x = (x); const typeof(y) _y = (y); _x < _y ? _x:_y;})

int main ()
{
        int i = 10;
        float a[5]={8.1,9.1,11.2,10.3,13.4};

        float  *p = a;
        float j;

        j =MIN(*p++,i);
        printf("%f\n",j);

        printf("%f\n",*p);

        return (0);
}

运行及输出
引用
beyes@linux-beyes:~/C/micro> ./micro3.exe
8.100000
9.100000

说明
应用上面程序中的宏,不再需要额外提供一个参数的类型。和上面的例子一样,不会产生副作用,最终用来比较的值是所希望的数组中的第一个元素 8.1。注意,在宏执行完后,指针还是要移动到数组的下一个元素。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值