Vous devez distinguer deux concepts distincts: la définition de fonction et la déclaration de symbole. "extern" est un modificateur de lien, un indice au compilateur sur l'endroit où le symbole auquel il est fait référence par la suite est défini (l'indice est "pas ici").
Si j'écris
extern int i;
dans la portée du fichier (en dehors d'un bloc fonctionnel) dans un fichier C, alors vous dites "la variable peut être définie ailleurs".
extern int f() {return 0;}
est à la fois une déclaration de la fonction f et une définition de la fonction f. La définition dans ce cas l'emporte sur l'externe.
extern int f();
int f() {return 0;}
est d'abord une déclaration, suivie de la définition.
L'utilisation de extern
est incorrecte si vous souhaitez déclarer et définir simultanément une variable d'étendue de fichier. Par exemple,
extern int i = 4;
donnera une erreur ou un avertissement, selon le compilateur.
L'utilisation de extern
est utile si vous souhaitez explicitement éviter la définition d'une variable.
Laisse-moi expliquer:
Disons que le fichier ac contient:
#include "a.h"
int i = 2;
int f() { i++; return i;}
Le fichier ah comprend:
extern int i;
int f(void);
et le fichier bc contient:
#include <stdio.h>
#include "a.h"
int main(void){
printf("%d\n", f());
return 0;
}
L'extern dans l'en-tête est utile, car il indique au compilateur pendant la phase de liaison, "c'est une déclaration et non une définition". Si je supprime la ligne dans ac qui définit i, lui alloue de l'espace et lui attribue une valeur, le programme ne devrait pas se compiler avec une référence non définie. Cela indique au développeur qu'il a fait référence à une variable, mais ne l'a pas encore définie. Si par contre, j'omets le mot-clé "extern" et supprime la int i = 2
ligne, le programme compile toujours - i sera défini avec une valeur par défaut de 0.
Les variables d'étendue de fichier sont implicitement définies avec une valeur par défaut de 0 ou NULL si vous ne leur attribuez pas explicitement de valeur, contrairement aux variables d'étendue de bloc que vous déclarez en haut d'une fonction. Le mot-clé extern évite cette définition implicite et permet ainsi d'éviter les erreurs.
Pour les fonctions, dans les déclarations de fonctions, le mot clé est en effet redondant. Les déclarations de fonction n'ont pas de définition implicite.