ProgrammationDéveloppeur C/Embedded

Expliquez la différence entre la déclaration et la définition de fonctions et de variables en C. Que se passe-t-il si ces règles sont enfreintes dans un projet multimodule ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En langage C, on distingue la déclaration (declaration) et la définition (definition).

  • Déclaration informe le compilateur de l'existence d'une fonction ou d'une variable ainsi que son type, mais ne réserve pas de mémoire.
  • Définition définit l'objet ou le corps de la fonction, réservant en fait de la mémoire pour la variable ou plaçant le code de la fonction.

Exemples :

// Déclaration (extern) extern int global_var; int func(int); // Définition int global_var = 42; int func(int x) { return x * 2; }

Dans un projet multimodule, les déclarations sont placées dans des fichiers d'en-tête, afin que les modules "soient informés les uns des autres", et les définitions uniquement dans un seul fichier source, afin d'éviter des conflits lors de l'édition de liens.

Question piégeuse

Peut-il y avoir plusieurs définitions identiques de la même variable (par exemple, int flag = 0;) dans différents fichiers source, s'ils incluent le même fichier d'en-tête ?

Réponse : Non ! Le fichier d'en-tête doit uniquement contenir la déclaration extern int flag;, et la définition de la variable doit être uniquement dans un fichier source (int flag = 0;). La non-conformité entraînera une erreur d'édition de liens en raison de la définition multiple.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans un grand projet, les variables globales ont été "réparties" dans les fichiers d'en-tête comme int counter = 0;. Ce qui a entraîné un doublon de définition en incluant cet en-tête. Conclusion : erreur de l'éditeur de liens lors de la compilation CI/CD — “definition multiple de counter”.


Histoire

Dans une bibliothèque de fonctions, des prototypes de fonctions ont été créés sans spécification de types, ce qui a été perçu par le compilateur comme une déclaration obsolète, et a ensuite conduit à une erreur en raison d'incompatibilités de signatures de fonctions entre les modules.


Histoire

Lors de la phase de test, il a été constaté que certaines variables n'étaient pas initialisées, car elles n'avaient été déclarées que comme extern, mais aucune initialisation n'était présente dans aucun des modules. Cela a conduit à des lectures de valeurs indésirables et à des bugs difficiles à détecter sur une plateforme embarquée.