Déclaration vs définition en C

Considérons le code:

int main(void) { int a; } 

Pour autant que je sache, int a; est une définition, car elle entraîne la réservation du stockage. Citant la norme C (ébauche du comité N1570 – 12 avril 2011):

6.7 / 5 Sémantique Une déclaration spécifie l’interprétation et les atsortingbuts d’un ensemble d’identifiants. Une définition d’un identifiant est une déclaration pour cet identifiant qui:

– pour un object, le stockage est réservé à cet object;

Voici la question: le compilateur peut optimiser le stockage, car nous n’utilisons pas la variable. Est alors int a; une déclaration alors? Et que se passe-t-il si nous faisons un printf("%p", &a) dans main(void) – le compilateur doit maintenant allouer le stockage, le concept de déclaration / définition dépend donc de l’utilisation ultérieure ou non de l’identifiant?

Le texte que vous avez cité dans 6.7 / 5 est en réalité censé être interprété dans le sens contraire de ce que vous avez fait: le texte dit que les définitions entraînent une allocation de stockage.

Le texte qui spécifie que int a; est une définition est ailleurs.

C est défini en termes de machine abstraite. Il y a du stockage alloué dans la machine abstraite. Que de la mémoire soit allouée ou non sur votre PC est sans rapport.

Est alors int a; une déclaration alors?

Oui.

En fait, chaque définition est aussi une déclaration . Une variable ne peut avoir qu’une seule définition, mais peut avoir plusieurs déclarations.

 int a; 

Ceci est une définition Il y a une mémoire allouée pour la variable a

 extern int a; 

Ceci est une déclaration. La mémoire n’est pas allouée car elle n’est pas définie.

Une fois qu’une variable est définie, vous pouvez utiliser l’adresse de celle-ci qui est totalement légale.

Une déclaration introduit un identifiant et décrit son type, qu’il s’agisse d’un type, d’un object ou d’une fonction. Une déclaration est ce dont le compilateur a besoin pour accepter les références à cet identifiant. Ce sont des déclarations:

 extern int bar; extern int g(int, int); 

Une définition instancie / implémente effectivement cet identifiant. C’est ce dont l’éditeur de liens a besoin pour lier des références à ces entités. Ce sont des définitions correspondant aux déclarations ci-dessus:

 int bar; int g(int lhs, int rhs) {return lhs*rhs;}