设为首页 加入收藏

TOP

C11标准的泛型机制
2015-12-15 23:09:08 来源: 作者: 【 】 浏览:3
Tags:C11 标准 机制

Apple LLVM4.0已经支持了C11标准中的关键特性——泛型机制。尽管C11中的泛型机制比起C++的来要显得简陋不少,但是在做库的时候仍然十分管用。


下面我们就来看一下C11标准中的泛型表达式。


C11中的泛型机制由关键字_Generic引出,其语法形式为:


_Generic ( assignment-expression , generic-assoc-list )


generic-assoc-list:


? ? generic-association


? ? generic-assoc-list , generic-association


generic-association:
? ? type-name : assignment-expression


? ? default : assignment-expression


下面给出C代码例子:


#define GENERAL_ABS(x)? _Generic((x), int:abs, float:fabsf, double:fabs)(x)


static void GenericTest(void)


{


? ? printf("int abs: %d\n", GENERAL_ABS(-12));


? ? printf("float abs: %f\n", GENERAL_ABS(-12.04f));


? ? printf("double abs: %f\n", GENERAL_ABS(-13.09876));


? ? int a = 10;


? ? int b = 0, c = 0;


? ?


? ? _Generic(a + 0.1f, int:b, float:c, default:b)++;


? ? printf("b = %d, c = %d\n", b, c);


? ?


? ? _Generic(a += 1.1f, int:b, float:c, default:b)++;


? ? printf("a = %d, b = %d, c = %d\n", a, b, c);


}


这边要注意的是,_Generic里的assignment-expression只获取其类型而不会对它做运行时计算。也就是说,编译器仅仅在编译时获得该表达式的类型,而不会产生任何其它指令。这个跟sizeof()、typeof(),以及C++中的typeid()和decltype()一样。


另外,generic-association-list中必须要有与assignment-expression类型相同的generic-association,否则编译会报错。当然,如果在generic-association-list中含有default处理,那么编译能顺利进行。如以下代码所示:


struct MyStruct { int a, b; } s;


_Generic("Hello", const char*:puts("OK!"));? ? // ERROR! "Hello"为char[6]类型


_Generic("Hello", char[6]:puts("OK!"));? ? // OK


_Generic((const char*)"Hello", const char*:puts("OK!"));? ? // OK


_Generic(s, int:puts("OK!"));? ? // ERROR


_Generic(s, struct MyStruct:puts("OK!"));? ? // OK


_Generic(s, int:puts("Yep!"), default:puts("Others"));? ? // OK


这里需要注意的是,_Generic表达式中,对于不满足类型匹配的表达式语句也会被编译器编译,确认其有效性。因此,对于不满足类型匹配的表达式犹如sizeof()、typeof()那样,只做编译,不做计算。比如,以下语句全是错误的:


const int g = 50;
? ?
typeof(g = 10) t = 200;? ? // ERROR
? ?
int f = sizeof(g = 100);? ? // ERROR
? ?
f = _Generic(g, int:sizeof(g), char:(g = 100, g), default:g + 10);? // ERROR


最后一行代码中,即便char:这个类型没匹配上,但是编译器仍然会报错。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Ubuntu 14.04下用GCC及gfortran编.. 下一篇Linux下使用POSIX Thread作多核多..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: