Selección genérica (C11)
Use la palabra clave _Generic
para escribir código que seleccione una expresión en tiempo de compilación según el tipo del argumento. Este funcionamiento es similar a la sobrecarga en C++, en la que el tipo de argumento selecciona a qué función llamar. En este caso, el tipo del argumento selecciona la expresión que se va a evaluar.
Por ejemplo, la expresión _Generic(42, int: "integer", char: "character", default: "unknown");
evalúa el tipo de 42
y busca el tipo coincidente, int
, en la lista. Lo encuentra y devuelve "integer"
.
Sintaxis
generic-selection
:
_Generic
( assignment-expression
, assoc-list
)
assoc-list
:
association
assoc-list
, association
association
:
type-name
: assignment-expression
default
: assignment-expression
A la primera assignment-expression
se le llama expresión de control. El tipo de la expresión de control se determina en tiempo de compilación y se compara con la assoc-list
para encontrar la expresión que se va a evaluar y devolver. La expresión de control no se evalúa. Por ejemplo, _Generic(intFunc(), int: "integer", default: "error");
no produce una llamada en tiempo de ejecución a intFunc
.
Cuando se determina el tipo de la expresión de control, const
, volatile
y restrict
se quitan antes de compararse con assoc-list
.
No se evaluarán las entradas de la assoc-list
que no se hayan elegido.
Restricciones
- La
assoc-list
no puede especificar el mismo tipo más de una vez. - La
assoc-list
no puede especificar tipos compatibles entre sí, como una enumeración y el tipo subyacente de esa enumeración. - Si una selección genérica no tiene un valor predeterminado, la expresión de control solo debe tener un nombre de tipo compatible en la lista de asociaciones genérica.
Ejemplo
Una manera de usar _Generic
se encuentra en una macro. El archivo de encabezado <tgmath.h> usa _Generic
para llamar a la función matemática correcta según el tipo de argumento. Por ejemplo, la macro para cos
asigna una llamada con un valor float a cosf
, mientras se asigna una llamada con un valor complex double a ccos
.
En el ejemplo siguiente se muestra cómo escribir una macro que identifique el tipo del argumento que le pase. Produce "unknown"
si no coincide ninguna entrada de la assoc-list
con la expresión de control:
// Compile with /std:c11
#include <stdio.h>
/* Get a type name string for the argument x */
#define TYPE_NAME(X) _Generic((X), \
int: "int", \
char: "char", \
double: "double", \
default: "unknown")
int main()
{
printf("Type name: %s\n", TYPE_NAME(42.42));
// The following would result in a compile error because
// 42.4 is a double, doesn't match anything in the list,
// and there is no default.
// _Generic(42.4, int: "integer", char: "character"));
}
/* Output:
Type name: double
*/
Requisitos
Compile con /std:c11
.
Windows SDK 10.0.20348.0 (versión 2104) o posterior. Consulte Windows SDK para descargar el SDK más reciente. Para obtener instrucciones sobre cómo instalar y usar el SDK para el desarrollo con C11 y C17, vea Instalación de la compatibilidad con C11 y C17 en Visual Studio.
Vea también
/std
(Especificar la versión estándar del lenguaje)
Matemáticas de tipo genérico