Généricité

Avant le C11 l’approche de la génériécité dans le langage était garantie par des règles de conversion construites dans le langage lui même. Lorsqu’une fonction travaille avec des entiers ou des flottants d’un certain type, si on lui fournit un entier d’un type différent, une conversion survient.


float fun(float nombre)
{
    return nombre * 2;
}

int main()
{
    fun(2.f); // type: float -> fonctionne
    fun(2); // type: int -> fonctionne
    fun(2.); // type: double -> fonctionne, avec avertissement
    fun(2l); // type: long int -> fonctionne
    fun(2ull); // type: unsigned long long -> fonctionne
}

L’avantage d’avoir cette conversion automatique est que hormis avoir à mémoriser les règles de conversion, il n’est nul besoin d’ajouter une systaxe générique pour des fonctions à opérandes de type variable. Il est laissé au compilateur d’écrire des version spécialisées de la fonction si besoin.

Cette générécité est omniprésente dans le langage. Par exemple une fonction void fun(float a, float b, float c, float d), si on l’appellait avec des arguments de type double, ceux i ne déborderaient pas sur les arguments voisins mais seront silencieusement (ou pas) convertis.

Regles de conversion

_Generic void *

Limitations dues à absence de tpye boolen et nullptr, peut etre résolues en C23