7.4. Plus d’informations sur les prototypes de fonction

Icône de l'outil pédagogique Plus d’informations sur les prototypes de fonction

Un prototype, c’est vraiment indispensable ?

Oui !!!
Si le compilateur "connaît" la fonction appelée (c'est‐à‐dire s'il a déjà compilé sa définition), le prototype est inutile pour lui. Mais l'utilisation d'une fonction a souvent lieu alors que la définition de la fonction n'est pas encore connue du compilateur : soit parce que la définition a lieu plus bas dans le même fichier source, soit parce que la définition est effectuée dans un autre fichier (cas très fréquent).

Grâce au prototype, le compilateur peut effectuer son travail lorsqu'il rencontre un appel de fonction :

– vérification du nombre d’arguments
– vérification de la concordance des types
– mise en place de conversions de type si elles sont nécessaires (et possibles).

En l'absence de prototype, le compilateur doit afficher un message (ou un Warning) d'erreur.

Si le compilateur est ancien ou mal configuré, il n’exige pas les prototypes. Il effectue donc moins de vérifications et, surtout, attribue à la fonction le type par défaut int : cela génère souvent des erreurs difficiles à détecter pendant l'exécution. Par exemple, la ligne y=sin(x), en l’absence de prototype, aura pour effet de mettre à 0 la variable y ! (la valeur renvoyée par la fonction sinus est convertie en entier, soit presque toujours 0).

→ Vérifiez que votre compilateur exige les prototypes (cherchez le menu Options du compilateur).


Dans l'exemple du début de chapitre, sans la directive #include <math.h>, un compilateur qui accepte de travailler sans prototype va supposer par défaut que la fonction sqrt fournit un résultat de type entier (int) ; il mettra alors en place une conversion de la valeur de retour en int, ce qui conduira à un résultat faux…

Les lignes de prototype et les directives #include ne génèrent aucune instruction exécutable. Mieux vaut en mettre trop que pas assez.

Faut‐il respecter à la lettre les types indiqués du prototype ?

Pas forcément !
Si le type de l'information transmise par l’utilisateur (cette information est appelée argument d’appel (ou paramètre effectif, plus compliqué)) ne coïncide pas avec le type qui figure dans le prototype, le compilateur force la conversion de la valeur transmise pour qu'elle corresponde au prototype (à condition que ce soit possible !). Ces conversions sont particulièrement utiles dans le cas des fonctions mathématiques, dont les prototypes ne comportent que des types double, mais qui sont fréquemment appelées avec des arguments d’appel int ou float :

y = sin(5) ; /* conversion en double faite par le compilateur */

Quel lien existe entre prototype et fichier en‐tête ?

Les fichiers en‐tête d'extension .h contiennent principalement des prototypes des fonction. Ainsi, math.h contient les prototypes de toutes les fonctions mathématiques disponibles en bibliothèque, stdio.h contient les prototypes des fonctions d’entrée/sortie standard (clavier, écran, fichier…).
Toute utilisation d'une fonction doit être précédée de l'inclusion du fichier en‐tête associé à la bibliothèque, pour que le compilateur dispose des prototypes :