Sintaxis y uso de muestra de _Generic en C11

Resuelto ApprenticeHacker asked hace 12 años • 3 respuestas

Escuché que C11 agregó genéricos. Busqué en Google un poco, miré algunos artículos, entendí que hay una nueva palabra clave ( _Generic) y todo. Pero parece que no puedo entenderlo todo.

¿Es algo así como los genéricos en C# o las plantillas en C++? ¿Alguien puede darme una breve explicación de la definición de genéricos de C11, su sintaxis y un ejemplo de uso sencillo?

ApprenticeHacker avatar Mar 21 '12 19:03 ApprenticeHacker
Aceptado

El mejor ejemplo que he visto inspiró el siguiente ejemplo (ejecutable), que desbloquea todo tipo de posibilidades extrañas para una introspección descifrada...

#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'
Alex Gray avatar Jun 25 '2013 06:06 Alex Gray

Utilizo CLion 1.2.4 y CLion no es compatible con C11 ahora, por lo que uso el siguiente código en GNU C99 en lugar de_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);
};
izhkymonte avatar Jan 19 '2016 13:01 izhkymonte