C11语言中_泛型的句法及样例用法

我听说 C11增加了泛型。我谷歌了一下,看了一些文章,明白了有一个新的关键字(_Generic)和所有。但我似乎无法全部理解。

它是类似于 C # 中的泛型还是 C + + 中的模板?有人能给我一个简短的解释 C11的泛型定义,它的语法和一个简单的例子使用例子?

51512 次浏览

This is a pretty good introduction. Here's the Overview:

Generic selection is implemented with a new keyword: _Generic. The syntax is similar to a simple switch statement for types:_Generic( 'a', char: 1, int: 2, long: 3, default: 0) evaluates to 2 (character constants are ints in C).

Basically it works like a kind of switch, where the labels are type names which are tested against the type of the first expression (the 'a' above). The result becomes the result of evaluating the _Generic().

The best example I have seen inspired the following (runnable) example, which unlocks all sorts of freaky possibilities for cracked-out introspection...

#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'

I use clion 1.2.4, and clion doesn't support c11 now, so I use following code in c99 instead of _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);
};