Namespaces
Variants

Generic selection (since C11)

From cppreference.net

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

_Generic , default

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