Qu’est-ce que cela signifie de déclarer une variable avec un spécificateur de classe de stockage mais pas de spécificateur de type?

Après avoir lu la spécification de grammaire ANSI C Yacc, j’ai remarqué que les suivantes étaient toutes valides:

register x; auto y; static z; extern q; 

Cela me semble étrange, car ma compréhension du type suggérerait qu’aucune de ces variables n’a de type. Qu’est-ce que cela signifie? Comment sont-ils typescripts? Combien de mémoire est allouée?

Avant C99, si aucun type n’était spécifié, sa valeur par défaut était int était supposée être supprimée dans C99, mais de nombreux compilateurs le prennent en charge même en mode C99. Par exemple, dans clang même en utilisant -std=c99 je ne reçois que les avertissements suivants par opposition aux erreurs:

 warning: type specifier missing, defaults to 'int' [-Wimplicit-int] register x; ~~~~~~~~ ^ warning: type specifier missing, defaults to 'int' [-Wimplicit-int] auto y; ~~~~ ^ warning: type specifier missing, defaults to 'int' [-Wimplicit-int] static z; ~~~~~~ ^ warning: type specifier missing, defaults to 'int' [-Wimplicit-int] extern q; ~~~~~~ ^ 

gcc ne fournit également qu’un avertissement dans ce cas, bien que l’utilisation de l’ -pedantic-errors entraîne gcc à générer des erreurs, ce qui est généralement le cas pour les extensions dans gcc et généralement pour clang to mais pas dans ce cas.

Si nous examinons le projet de norme C99, la section Transférer dit:

[…] Les principaux changements par rapport à l’édition précédente incluent:

et comprend la puce suivante:

– supprime int implicite

Mettre à jour

Extrait de la section Justification de la norme internationale Standard – Langages de programmation – C, section 6.7.2 :

nouvelle fonctionnalité de C99: dans C89, tous les spécificateurs de type pouvaient être omis des spécificateurs de déclaration d’une déclaration. Dans un tel cas, int était impliqué. Le Comité a décidé que le danger inhérent à cette caractéristique l’emportait sur sa commodité et a donc été supprimé. L’effet est de garantir la production d’un diagnostic qui détectera une catégorie supplémentaire d’erreurs de programmation. Après avoir émis le diagnostic, une implémentation peut choisir de supposer un int implicite et de continuer à traduire le programme afin de prendre en charge le code source existant exploitant cette fonctionnalité.

La grammaire que vous utilisez est antérieure à C99 mais, autant que je sache, une version plus récente mise à jour pour refléter C11 ne diffère pas beaucoup en ce qui concerne les spécificateurs de type dans une déclaration. Donc, la grammaire dans cette situation n’est pas suffisante pour appliquer cette contrainte. Vous devez accéder à la section 6.7.2 spécificateurs de type standard et voir ce qui suit:

Au moins un spécificateur de type doit figurer dans les spécificateurs de déclaration de chaque déclaration et dans la liste qualificateur-qualificateur de chaque déclaration de structure et nom de type.