Partager via


Sélection générique (C11)

Utilisez le mot clé _Generic pour écrire du code qui sélectionne une expression au moment de la compilation en fonction du type de l’argument. Il est similaire à la surcharge en C++ où le type de l’argument sélectionne la fonction à appeler. Dans ce cas, le type de l’argument sélectionne l’expression à évaluer.

Par exemple, l’expression _Generic(42, int: "integer", char: "character", default: "unknown"); évalue le type de 42 et recherche le type correspondant, int, dans la liste. Il le trouve et retourne "integer".

Syntaxe

generic-selection:
_Generic ( assignment-expression, assoc-list )

assoc-list:
association
assoc-list, association

association:
type-name : assignment-expression
default : assignment-expression

La première assignment-expression est appelée expression de contrôle. Le type de l’expression de contrôle est déterminé au moment de la compilation et mis en correspondance avec la assoc-list pour trouver l’expression à évaluer et à retourner. L’expression de contrôle n’est pas évaluée. Par exemple, _Generic(intFunc(), int: "integer", default: "error"); n’entraîne pas d’appel à intFunc au moment de l’exécution.

Lorsque le type de l’expression de contrôle est déterminé, const, volatile et restrict sont supprimés avant la mise en correspondance avec assoc-list.

Les entrées de la assoc-list qui ne sont pas choisies ne sont pas évaluées.

Contraintes

  • La assoc-list ne peut pas spécifier le même type plusieurs fois.
  • La assoc-list ne peut pas spécifier des types compatibles entre eux, tels qu’une énumération et le type sous-jacent de celle-ci.
  • Si une sélection générique n’a pas de valeur par défaut, l’expression de contrôle ne doit avoir qu’un seul nom de type compatible dans la liste d’associations génériques.

Exemple

Une façon d’utiliser _Generic consiste à l’utiliser dans une macro. Le fichier d’en-tête <tgmath.h> utilise _Generic pour appeler la fonction mathématique appropriée en fonction du type d’argument. Par exemple, la macro pour cos mappe un appel avec une valeur flottante à cosf, et un appel avec un double complexe à ccos.

L’exemple suivant montre comment écrire une macro qui identifie le type de l’argument que vous lui transmettez. Elle produit "unknown" si aucune entrée dans la assoc-list ne correspond à l’expression de contrôle :

// 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
*/

Spécifications

Compilez avec /std:c11.

SDK Windows 10.0.20348.0 (version 2104) ou ultérieure. Pour télécharger le Kit de développement logiciel (SDK) le plus récent, consultez SDK Windows. Pour obtenir des instructions sur l’installation et l’utilisation du Kit de développement logiciel (SDK) pour le développement en C11 et C17, consultez Installer la prise en charge de C11 et C17 dans Visual Studio.

Voir aussi

/std (Spécifier la version du standard du langage)
Mathématiques de type générique