Namespaces
Variants

Generic selection (since C11)

From cppreference.net

Fournit un moyen de choisir l'une de plusieurs expressions à la compilation, en fonction du type d'une expression de contrôle

Table des matières

Syntaxe

_Generic ( expression-contrôle , liste-associations ) (depuis C11)

association-list est une liste d'associations séparées par des virgules, chacune ayant la syntaxe

nom-de-type : expression
default : expression

type-name - tout type d'objet complet object type qui n'est pas modifiable de manière variable (c'est-à-dire pas VLA ou pointeur vers VLA).
controlling-expression - toute expression (sauf l' comma operator ) dont le type doit être compatible avec l'un des type-name s si l'association default n'est pas utilisée
expression - toute expression (sauf l' comma operator ) de tout type et catégorie de valeur

Aucun couple de type-name dans la association-list ne peut spécifier des types compatibles . Il ne peut y avoir qu'une seule association utilisant le mot-clé default . Si default n'est pas utilisé et qu'aucun des type-name n'est compatible avec le type de l'expression de contrôle, le programme ne compilera pas.

Explication

Premièrement, le type de controlling-expression subit les lvalue conversions . La conversion est effectuée uniquement dans le domaine du type : elle supprime les qualificatifs cvr de plus haut niveau et l'atomicité, et applique les transformations tableau-vers-pointeur/fonction-vers-pointeur au type de l'expression de contrôle, sans initier d'effets secondaires ni calculer de valeurs.

Le type après conversion est comparé avec les type-name s de la liste d'associations.

Si le type est compatible avec le type-name d'une des associations, alors le type, la valeur et la value category de la sélection générique sont le type, la valeur et la value category de l' expression qui apparaît après le deux-points pour ce type-name .

Si aucun des type-name n'est compatible avec le type de l' controlling-expression , et que l'association default est fournie, alors le type, la valeur et la catégorie de valeur de la sélection générique sont le type, la valeur et la catégorie de valeur de l'expression après l'étiquette default : .

Notes

L' expression-de-contrôle et les expressions des sélections qui ne sont pas choisies ne sont jamais évaluées.

En raison des conversions de lvalue, "abc" correspond à char * et non à char [ 4 ] , et ( int const ) { 0 } correspond à int , et non à const int .

Toutes les catégories de valeur , y compris les désignateurs de fonction et les expressions void, sont autorisées comme expression s dans une sélection générique, et si sélectionnées, la sélection générique elle-même a la même catégorie de valeur.

Les macros mathématiques génériques de <tgmath.h> , introduites en C99, étaient implémentées de manière spécifique au compilateur. Les sélections génériques, introduites en C11, ont donné aux programmeurs la capacité d'écrire un code similaire dépendant du type.

La sélection générique est similaire à la surcharge en C++ (où l'une de plusieurs fonctions est choisie au moment de la compilation en fonction des types des arguments), sauf qu'elle effectue la sélection entre des expressions arbitraires.

Mots-clés

_Generic , default

Exemple

#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
}

Sortie :

cbrt(8.0) = 2.000000
cbrtf(3.375) = 1.500000

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C publiées antérieurement.

DR Applicable à Comportement publié Comportement correct
DR 481 C11 il n'était pas suffisamment spécifié si l'expression de contrôle subit des conversions de lvalue elle les subit

Références

  • Norme C23 (ISO/CEI 9899:2024) :
  • 6.5.1.1 Sélection générique (p: TBD)
  • Norme C17 (ISO/CEI 9899:2018) :
  • 6.5.1.1 Sélection générique (p: 56-57)
  • Norme C11 (ISO/CEI 9899:2011) :
  • 6.5.1.1 Sélection générique (p: 78-79)

Voir aussi

Documentation C++ pour Templates