zoukankan      html  css  js  c++  java
  • GCC4.7+中如何替代C11中的_Generic

    C11标准中,一个非常重大的特性更新就是增加了Generic Selection这个特性。这个特性能使得C11支持轻量级的泛型编程,使得可以把一组具有不同类型而却有相同功能的函数抽象为一个接口。

    对于_Generic的使用可参见俺这篇博文——http://www.cnblogs.com/zenny-chen/archive/2012/09/20/2695381.html


    由于GCC至今还没有支持C11标准的Generic Selection,不过GCC似乎从4.0版本开始就支持了一些内建的编译时函数(这些函数类似于sizeof),包括比较常见的typeof。这里,我们通过组合使用__builtin_choose_expr以及__builtin_types_compatible_p就可实现C11的Generic Selection功能。

    我们先看一下__builtin_choose_expr的原型:

    type __builtin_choose_expr (const_exp, exp1, exp2)

    这里要注意的是这个函数的第一个参数必须是常量表达式,因为之前我已经说过,它属于编译时行为,而非运行时行为,跟sizeof和typeof一样。这个函数是一个谓词函数,如果const_expr的结果非0,那么生成exp1,且返回类型type也与exp1表达式的类型一致;否则生成exp2,并且返回类型type也与exp2的类型一致。由于是编译时行为,因此exp1与exp2表达式所产生的目标代码是互斥的,生成了exp1就不会存在exp2。下面举一个简单例子:

    int main(void)
    {
        (void)__builtin_choose_expr(100 < 1000, puts("OK"), puts("NG"));
    
        int a = __builtin_choose_expr(sizeof('a') == 1, "YES", 100);
        printf("The value is: %d
    ", a);
    }


    然后,我们再看一下编译时内建函数__builtin_types_compatible_p,其原型为——

    int __builtin_types_compatible_p (type1, type2)

    这个函数是比较type1与type2两个类型(注意,这里是类型,而不是表达式),如果两个类型的非限定版本相兼容,那么返回1,否则返回0。这里也举个简单的例子:

    int main(void)
    {
        int r = __builtin_types_compatible_p(typeof('a'), char);
        printf("result 1 is: %d
    ", r);
        
        r = __builtin_types_compatible_p(typeof('a'), const int);
        printf("result 2 is: %d
    ", r);
    }


    好。介绍完了这两个编译时内建函数之后,我们就来看看如何将它们组合起来以实现C11 Generic Selection的功能:

    int main(void)
    {
        _Generic('a', int:puts("WOW"), char:puts("Ja~~"), default:puts("Oui~~"));
    
        // equivalent
        (void)__builtin_choose_expr(__builtin_types_compatible_p(typeof('a'), int), puts("WOW"),
                                    __builtin_choose_expr(__builtin_types_compatible_p(typeof('a'), char), puts("Ja~~"), puts("Oui~~")));
    }

    这里要注意的是,使用这些内建函数必须开启GNU规范,4.7以上版本的GCC可直接用C11标准了,开启方法为:在命令选项中添加-std=gnu11

  • 相关阅读:
    菜单项向子页面传递参数
    Grid中添加链接,打开选项卡页面
    FineUI与百度地图简单示例 (转帖)
    AppBox中main树节点单击事件JS(还有叶子的节点的页面链接)
    FineUI中在一个页面中通过控件事件(JS)向父页面中添加Tab页
    如何使用button在tab中新建打开一个链接页
    系统service
    官员详解官场对领导称谓讲究:叫大不叫小
    搞笑对话
    陆琪:男人生存的意义,就是赚钱养老婆
  • 原文地址:https://www.cnblogs.com/zenny-chen/p/3303560.html
Copyright © 2011-2022 走看看