Generic selection (since C11)
Proporciona una forma de elegir una de varias expresiones en tiempo de compilación, basándose en un tipo de expresión controladora
Contenidos |
Sintaxis
_Generic
(
expresión-de-control
,
lista-de-asociaciones
)
|
(desde C11) | ||||||||
donde association-list es una lista de asociaciones separadas por comas, cada una de las cuales tiene la sintaxis
nombre-de-tipo
:
expresión
|
|||||||||
default
:
expresión
|
|||||||||
donde
| type-name | - | cualquier tipo de objeto completo que no esté modificado variablemente (es decir, no VLA o puntero a VLA). |
| controlling-expression | - | cualquier expresión (excepto el operador coma ) cuyo tipo debe ser compatible con uno de los type-name s si no se utiliza la asociación default |
| expression | - | cualquier expresión (excepto el operador coma ) de cualquier tipo y categoría de valor |
No dos type-name s en la association-list pueden especificar tipos compatibles . Solo puede haber una asociación que utilice la palabra clave default . Si default no se utiliza y ninguno de los type-name s es compatible con el tipo de la expresión de control, el programa no compilará.
Explicación
Primero, el tipo de controlling-expression sufre lvalue conversions . La conversión se realiza únicamente en el dominio del tipo: descarta los calificadores cvr de nivel superior y la atomicidad, y aplica transformaciones de array-a-pointer/función-a-pointer al tipo de la expresión de control, sin iniciar efectos secundarios ni calcular valores.
El tipo después de la conversión se compara con type-name s de la lista de asociaciones.
Si el tipo es compatible con el type-name de una de las asociaciones, entonces el tipo, valor y value category de la selección genérica son el tipo, valor y categoría de valor de la expression que aparece después de los dos puntos para ese type-name .
Si ninguno de los
type-name
s es compatible con el tipo de la
controlling-expression
, y se proporciona la asociación
default
, entonces el tipo, valor y categoría de valor de la selección genérica son el tipo, valor y categoría de valor de la expresión después de la etiqueta
default :
.
Notas
La controlling-expression y las expression s de las selecciones que no son elegidas nunca son evaluadas.
Debido a las conversiones de lvalue, "abc" coincide con char * y no con char [ 4 ] y ( int const ) { 0 } coincide con int , y no con const int .
Todas las categorías de valor , incluyendo designadores de función y expresiones void, están permitidas como expresión s en una selección genérica, y si son seleccionadas, la propia selección genérica tiene la misma categoría de valor.
Las macros matemáticas genéricas de tipo de <tgmath.h> , introducidas en C99, se implementaron de manera específica del compilador. Las selecciones genéricas, introducidas en C11, dieron a los programadores la capacidad de escribir código dependiente del tipo similar.
La selección genérica es similar a la sobrecarga en C++ (donde una de varias funciones se elige en tiempo de compilación según los tipos de los argumentos), excepto que realiza la selección entre expresiones arbitrarias.
Palabras clave
Ejemplo
#include <math.h> #include <stdio.h> // Possible implementation of the tgmath.h macro cbrt #define cbrt(X) _Generic((X), \ long double: cbrtl, \ default: cbrt, \ float: cbrtf \ )(X) int main(void) { double x = 8.0; const float y = 3.375; printf("cbrt(8.0) = %f\n", cbrt(x)); // selects the default cbrt printf("cbrtf(3.375) = %f\n", cbrt(y)); // converts const float to float, // then selects cbrtf }
Salida:
cbrt(8.0) = 2.000000 cbrtf(3.375) = 1.500000
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C publicados anteriormente.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| DR 481 | C11 | no estaba especificado suficientemente si la expresión de control sufre conversiones de lvalue | sí las sufre |
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 6.5.1.1 Generic selection (p: TBD)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 6.5.1.1 Generic selection (p: 56-57)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 6.5.1.1 Generic selection (p: 78-79)
Véase también
|
Documentación de C++
para
Templates
|