Le système de types en C est apparu à l'aube du langage (fin des années 1960 - début des années 1970). Une typage statique stricte permet au compilateur de vérifier la conformité des types des variables, des expressions et des valeurs retournées avant l'exécution du programme.
Historique de la question :
La typage statique a été introduite pour prévenir à l'avance des erreurs qui ne pouvaient être détectées qu'à l'exécution. Au fil du temps, le système de types en C s'est progressivement complexifié pour soutenir de nouvelles plateformes et styles de programmation.
Problème :
Une erreur de non-conformité des types peut entraîner des conséquences imprévisibles : corruption de la mémoire, calculs erronés, plantage du programme. Sans vérification statique, il est difficile d'éviter de telles situations.
Solution :
Le code en C vérifie les types des variables et des expressions au moment de la compilation. Par exemple, il n'est pas possible d'assigner un pointeur sur int à une variable de type float* sans un casting explicite. Cela empêche de nombreuses erreurs.
Exemple de code :
int x = 5; double y = 3.14; y = x; // élargissement implicite du type int -> double int* p = &x; double* q = (double*)p; // autorisé, mais non sécurisé !
Caractéristiques clés :
Pourquoi en C peut-on "convertir" n'importe quel pointeur en void et le reconvertir sans perte d'information ?*
Le standard C garantit qu'un pointeur de n'importe quel type peut être converti en void* et reconverti sans perte d'information. Cela est utilisé, par exemple, dans les fonctions de la bibliothèque standard (malloc, memcpy). Cependant, la reconversion d'un void* en un type incorrect entraîne un comportement indéfini.
Comment se produit la conversion implicite des types lors des opérations arithmétiques entre int et float ?
C "promouvait" automatiquement le type de plus petite taille au type plus large, généralement à double ou float. Par exemple, si un int est additionné à un float, l'int est converti en float avant l'opération.
int a = 10; float b = 2.5f; float c = a + b; // a est d'abord converti en float
Est-il vrai qu'un pointeur sur void ne peut pas être déférencé ?
Oui, un pointeur sur void pointe vers des données de type indéfini et ne peut pas être déférencé directement, car le compilateur ne connaît pas la taille du type. Pour le déférencer, il doit être converti en un type spécifique :
void* ptr = ...; int x = *(int*)ptr;
Passage de pointeurs de types différents à une fonction prenant void*, sans conversion correcte par la suite :
void print_value(void* data) { printf("%d ", *(int*)data); // erreur si data est un double* } double d = 1.5; print_value(&d); // incorrect
Avantages :
Inconvénients :
Utilisation de la typage statique et de conversions explicites avec vérification :
void print_int(void* data) { if (data) { printf("%d ", *(int*)data); } } int value = 42; print_int(&value);
Avantages :
Inconvénients :