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.