Sintassi e utilizzo di esempio di _Generic in C11

Ho sentito C11 aggiungere farmaci generici. Ho cercato un po ‘su google, ho letto alcuni articoli, ho capito che c’è una nuova parola chiave ( _Generic ) e tutto il resto. Ma non riesco a cogliere tutto.

È qualcosa di simile ai generici in C # o ai modelli in C ++? Qualcuno può darmi una breve spiegazione della definizione di generici C11, la sua syntax e un semplice esempio di utilizzo del campione?

Questa è una buona introduzione. Ecco la panoramica:

La selezione generica viene implementata con una nuova parola chiave: _Generic. La syntax è simile a una semplice istruzione switch per i tipi: _Generic( 'a', char: 1, int: 2, long: 3, default: 0) valutato su 2 (le costanti di carattere sono interi in C).

Fondamentalmente funziona come un tipo di switch , in cui le etichette sono nomi di tipo testati rispetto al tipo della prima espressione (la 'a' sopra). Il risultato diventa il risultato della valutazione di _Generic() .

Il miglior esempio che ho visto ha ispirato il seguente esempio (eseguibile), che sblocca ogni sorta di strane possibilità per un’introspezione screpolata …

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

Io uso Clion 1.2.4, e Clion non supporta c11 ora, quindi uso il seguente codice in c99 invece di _Generic

 #include  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); };