C11中_Generic的语法和样例用法

我听说C11增加了仿制药。 我GOOGLE了一下,看了一些文章,了解有一个新的关键字( _Generic )和所有。 但我似乎无法把握这一切。

是类似于C#中的generics或C ++中的模板? 任何人都可以给我简要的解释generics的C11定义,它的语法和一个简单的示例用法示例?

这是一个很好的介绍。 以下是概述:

通用select使用新的关键字:_Generic来实现。 语法与types的简单switch语句相似: _Generic( 'a', char: 1, int: 2, long: 3, default: 0)计算结果为2(字符常量是C中的整数)。

基本上,它就像一种switch ,其中标签是types名称,这是根据第一个expression式(上面的'a' )的types进行testing的。 结果成为评估_Generic()的结果。

我见过的最好的例子启发了下面的(可运行的)例子,它解开了各种怪异的内省的可能性…

 #include <stdio.h> #include <stddef.h> #include <stdint.h> #define typename(x) _Generic((x), /* Get the name of a type */ \ \ _Bool: "_Bool", unsigned char: "unsigned char", \ char: "char", signed char: "signed char", \ short int: "short int", unsigned short int: "unsigned short int", \ int: "int", unsigned int: "unsigned int", \ long int: "long int", unsigned long int: "unsigned long int", \ long long int: "long long int", unsigned long long int: "unsigned long long int", \ float: "float", double: "double", \ long double: "long double", char *: "pointer to char", \ void *: "pointer to void", int *: "pointer to int", \ default: "other") #define fmt "%20s is '%s'\n" int main() { size_t s; ptrdiff_t p; intmax_t i; int ai[3] = {0}; return printf( fmt fmt fmt fmt fmt fmt fmt fmt, "size_t", typename(s), "ptrdiff_t", typename(p), "intmax_t", typename(i), "character constant", typename('0'), "0x7FFFFFFF", typename(0x7FFFFFFF), "0xFFFFFFFF", typename(0xFFFFFFFF), "0x7FFFFFFFU", typename(0x7FFFFFFFU), "array of int", typename(ai)); } 
  ╔═══════════════╗ ═════════════════╣ Amazeballs... ╠═════════════════════════════════════ ╚═══════════════╝ size_t is 'unsigned long int' ptrdiff_t is 'long int' intmax_t is 'long int' character constant is 'int' 0x7FFFFFFF is 'int' 0xFFFFFFFF is 'unsigned int' 0x7FFFFFFFU is 'unsigned int' array of int is 'other' 

我使用clion 1.2.4,并且clion现在不支持c11,所以我在c99中使用下面的代码而不是_Generic

 #include <stdio.h> int main(int argc, char **argv) { char *s; if (__builtin_types_compatible_p(__typeof__(s), long)) { puts("long"); } else if (__builtin_types_compatible_p(__typeof__(s), char*)) { puts("str"); } return (0); };