Pourquoi auto a = 1; comstackr en C?

Le code:

int main(void) { auto a=1; return 0; } 

obtient compilé sans erreurs par le compilateur MS Visual Studio 2012, lorsque le fichier a l’extension .c. J’ai toujours pensé que lorsque vous utilisez l’extension .c, la compilation devrait être conforme à la syntaxe C, et non C ++. De plus, pour autant que je sache, auto sans type n’est autorisé qu’en C ++ depuis C ++ 11, ce qui signifie que le type est déduit de l’initialiseur.

Est-ce que cela signifie que mon compilateur ne colle pas à C, ou est-ce que le code est correct en langage C?

auto est un ancien mot-clé C qui signifie “scope locale”. auto a est identique à auto int a , et comme la scope locale est la valeur par défaut pour une variable déclarée dans une fonction, elle est également identique à int a dans cet exemple.

Ce mot-clé est en fait un rest du prédécesseur B de C, où il n’y avait pas de type de base: tout était int , pointeur sur int , tableau d’ int . (*) Les déclarations seraient soit auto soit extrn [sic]. C a hérité de la règle par défaut “everything is int “, vous pouvez donc déclarer des entiers avec

 auto a; extern b; static c; 

ISO C s’en est débarrassé, mais de nombreux compilateurs l’acceptent toujours pour la compatibilité ascendante. Si cela vous semble peu familier, alors vous devriez comprendre qu’une règle connexe est à l’œuvre dans

 unsigned d; // actually unsigned int 

ce qui est encore commun dans le code moderne.

C ++ 11 a réutilisé le mot-clé, que peu de programmeurs C ++, voire aucun, utilisaient avec la signification d’origine, pour son inférence de type. C’est surtout sûr car la règle “Tout est int ” de C a déjà été supprimée dans C ++ 98; la seule chose qui casse est auto T a , que personne n’utilisait de toute façon. (Quelque part dans ses articles sur l’histoire du langage , Stroustrup commente, mais je ne trouve pas la référence exacte pour le moment.)

(*) La gestion des chaînes dans B était intéressante: vous utiliseriez des tableaux de type int et empaquettiez plusieurs caractères dans chaque membre. B était en fait BCPL avec une syntaxe différente.

Ceci est à la fois une réponse et un commentaire étendu à Non, ce n’est pas légal C depuis 1999. Aucun compilateur C moderne et correct ne le permet.

Oui, auto a=1; est illégal en C1999 (et également en C2011). Le fait que ce soit désormais illégal ne signifie pas qu’un compilateur C moderne doit rejeter le code contenant de telles constructions. Je dirais exactement le contraire, qu’un compilateur C moderne et décent doit toujours permettre cela.

Clang et gcc le font tout simplement lors de la compilation de l’exemple de code dans la question par rapport aux versions 1999 ou 2011 de la norme. Les deux compilateurs émettent un diagnostic, puis continuent comme si la déclaration répréhensible avait été auto int a=1; .

À mon avis, c’est ce qu’un compilateur décent devrait faire. En émettant un diagnostic, clang et gcc sont entièrement conformes à la norme. La norme ne dit pas qu’un compilateur doit rejeter le code illégal. La norme dit simplement qu’une implémentation conforme doit produire au moins un message de diagnostic si une unité de traduction contient une violation d’une règle ou d’une contrainte de syntaxe (5.1.1.3).

Étant donné le code qui contient des constructions illégales, tout compilateur décent tentera de comprendre le code illégal afin que le compilateur puisse trouver la prochaine erreur dans le code. Un compilateur qui s’arrête à la première erreur n’est pas un très bon compilateur. Il existe un moyen de donner un sens à auto a=1 , qui consiste à appliquer la règle “implicite int”. Cette règle force le compilateur à interpréter auto a=1 comme s’il était auto int a=1 lorsque le compilateur est utilisé en mode C90 ou K & R.

La plupart des compilateurs rejettent généralement le code (à rejeter: refuser de générer un fichier object ou un exécutable) qui contient une syntaxe illégale. C’est un cas où les auteurs du compilateur ont décidé que ne pas comstackr n’est pas la meilleure option. La meilleure chose à faire est d’émettre un diagnostic, de corriger le code et de continuer. Il y a trop de code hérité avec des constructions telles que register a=1; . Le compilateur devrait être capable de comstackr ce code en mode C99 ou C11 (avec un diagnostic, bien sûr).

auto a une signification en C et C++ avant la norme 2011. Cela signifie qu’une variable a une durée de vie automatique, c’est-à-dire une durée de vie déterminée par la scope . Ceci est opposé à, par exemple, static durée de vie static , où une variable dure “pour toujours”, indépendamment de la scope. auto est la durée de vie par défaut et n’est presque jamais explicitement expliquée. C’est pourquoi il était prudent de changer la signification en C++ .

Maintenant, dans C , avant le standard 99, si vous ne spécifiez pas le type d’une variable, sa valeur par défaut est int .

Donc, avec auto a = 1; vous déclarez (et définissez) une variable int , dont la durée de vie est déterminée par la scope.

(“durée de vie” s’appelle plus correctement “durée de stockage”, mais je pense que c’est peut-être moins clair).

Dans C, et les dialectes historiques de C ++, auto est un mot-clé signifiant qu’un stockage automatique a un. Comme il ne peut être appliqué qu’aux variables locales, qui sont automatiques par défaut, personne ne les utilise; c’est pourquoi le C ++ a maintenant réutilisé le mot-clé.

Historiquement, C a autorisé les déclarations de variables sans spécificateur de type; le type par défaut est int . Donc, cette déclaration est équivalente à

 int a=1; 

Je pense que cela est déconseillé (et peut-être interdit) dans le C moderne; mais certains compilateurs populaires utilisent C90 par défaut (ce qui, je pense, le permet), et n’ennuient que les avertissements si vous les demandez spécifiquement. Comstackr avec GCC et spécifier C99 avec -std=c99 , ou activer l’avertissement avec -Wimplicit-int ou -Wimplicit-int , donne un avertissement:

 warning: type defaults to 'int' in declaration of 'a' 

En C, auto signifie la même chose que le register en C ++ 11: cela signifie qu’une variable a une durée de stockage automatique.

Et en C avant C99 (et le compilateur de Microsoft ne supporte pas C99 ni C11, bien qu’il puisse en supporter certaines parties), le type peut être omis dans de nombreux cas, où il sera par défaut int .

Il ne prend pas du tout le type de l’initialiseur. Vous venez de choisir un initialiseur compatible.

Le type de compilation Visual Studio est disponible avec right click on file -> Properties -> C/C++ -> Advanced -> Comstack As . Pour vous assurer qu’il est compilé en tant qu’option C force /TC . Dans ce cas, c’est ce que larsmans a dit (ancien mot auto clé auto C). Il pourrait être compilé en C ++ sans que vous le sachiez.

Une classe de stockage définit la scope (visibilité) et la durée de vie des variables et / ou des fonctions dans un programme C.

Il existe des classes de stockage suivantes qui peuvent être utilisées dans un programme C

 auto register static extern 

auto est la classe de stockage par défaut pour toutes les variables locales.

 { int Count; auto int Month; } 

L’exemple ci-dessus définit deux variables avec la même classe de stockage. auto ne peut être utilisé que dans les fonctions, c’est-à-dire les variables locales.

int est le type par défaut pour auto dans le code ci-dessous:

 auto Month; /* Equals to */ int Month; 

Le code ci-dessous est légal aussi:

 /* Default-int */ main() { reurn 0; }