Sintaxis y Ejemplo de Uso de Genérico en C11


Escuché que C11 agregó genéricos. He buscado un poco en Google, he mirado algunos artículos, he entendido que hay una nueva palabra clave (_Generic) y todo. Pero no puedo entenderlo todo.

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

Author: Sourav Ghosh, 2012-03-21

3 answers

Esta es una introducción bastante buena. Aquí está el resumen:

La selección genérica se implementa con una nueva palabra clave: _Generic. La sintaxis es similar a una instrucción simple switch para tipos: _Generic( 'a', char: 1, int: 2, long: 3, default: 0) evalúa a 2 (las constantes de caracteres son ints en C).

Básicamente funciona como una especie de switch, donde las etiquetas son nombres de tipo que se prueban contra el tipo de la primera expresión (el 'a' anterior). El resultado se convierte en el resultado de la evaluación de la _Generic().

 41
Author: unwind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-21 12:22:30

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

#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'
 67
Author: Alex Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-27 03:05:42

Uso clion 1.2.4, y clion no soporta c11 ahora, así que uso el siguiente código en 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);
};
 4
Author: izhkymonte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-19 13:38:38