Le code:
int main(void)
{
auto a=1;
return 0;
}
est compilé sans erreur par le compilateur MS Visual Studio 2012, lorsque le fichier porte l'extension .c. J'ai toujours pensé que lorsque vous utilisez l'extension .c, la compilation doit ê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, où cela signifie que le type est déduit de l'initialiseur.
Cela signifie-t-il que mon compilateur ne s'en tient pas à C, ou le code est-il réellement correct en langage C?
int
a été supprimé de la norme C en 1999.Réponses:
auto
est un ancien mot-clé C qui signifie "portée locale".auto a
est identique àauto int a
, et comme la portée locale est la valeur par défaut pour une variable déclarée à l'intérieur d'une fonction, elle est également la même queint a
dans cet exemple.Ce mot-clé est en fait un reste du prédécesseur B de C, où il n'y avait pas de types de base: tout était
int
, pointeur versint
, tableau deint
. (*) Les déclarations seraient soitauto
ouextrn
[sic]. C a hérité du "tout estint
" comme règle par défaut, vous pouvez donc déclarer des entiers avecISO C s'est débarrassé de cela, mais de nombreux compilateurs l'acceptent toujours pour la compatibilité descendante. Si cela ne vous semble pas familier, vous devez vous rendre compte qu'une règle connexe est à l'œuvre dans
ce qui est encore courant dans le code moderne.
C ++ 11 a réutilisé le mot-clé, que peu ou pas de programmeurs C ++ utilisaient avec la signification d'origine, pour son inférence de type. Ceci est généralement sûr car la
int
règle «tout est » de C avait déjà été supprimée dans C ++ 98; la seule chose qui casseauto T a
, c'est que personne n'utilisait de toute façon. (Quelque part dans ses articles sur l'histoire de la langue , Stroustrup commente cela, mais je ne trouve pas la référence exacte pour le moment.)(*) La gestion des chaînes en B était intéressante: vous utiliseriez des tableaux
int
et regrouperiez plusieurs caractères dans chaque membre. B était en fait BCPL avec une syntaxe différente.la source
-Werror
.C'est à la fois une réponse et un commentaire étendu à Non, ce n'est pas légal depuis 1999. Aucun compilateur C moderne décent ne le permet.
Oui,
auto a=1;
est illégal dans C1999 (et aussi C2011). Ce n'est pas parce que c'est maintenant illégal qu'un compilateur C moderne devrait rejeter le code qui contient de telles constructions. Je dirais exactement le contraire, qu'un compilateur C moderne et décent doit encore permettre cela.Clang et gcc font exactement cela 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 de syntaxe ou d'une contrainte (5.1.1.3).
Étant donné le code qui contient des constructions illégales, tout compilateur décent essaiera de donner un sens au code illégal afin que le compilateur puisse trouver l'erreur suivante 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 "implicit int". Cette règle force le compilateur à interpréterauto a=1
comme si c'était le casauto 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 objet 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 compiler n'était 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é parsemé de constructions telles que
register a=1;
. Le compilateur devrait être capable de compiler ce code en mode C99 ou C11 (avec un diagnostic, bien sûr).la source
-ffs-please-stop-allowing-constructs-from-some-previous-millennium
option de compilateur, ou plus succinctement, une-fstrict-compliance
option. Grommelant au compilateur: "Quand j'ai utilisé -std = c11, je ne m'attendais pas à ce que l'ancien kruft K&R compile. En fait, je voulais qu'il ne compile pas !"-std=c99
être plus strict serait un pas dans la bonne direction :)gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror
(ce que j'utilise régulièrement, même sur le code des questions sur SO), alors vous vous rapprochez assez de ce que vous voulez. J'aimerais que GCC soit par défaut au moins-std=c99
et de préférence-std=c11
(ou-std=gnu11
,; ils le feraient plus probablement), mais d'ici là, ... Vous pouvez modifier ces options;-pedantic
,-Wshadow
,-Wold-style-declaration
Et d'autres peuvent être utiles, mais cela est un bon départ ensemble d'options.-pedantic-errors
auto
a une signification dansC
etC++
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 portée . Ceci est opposé, par exemple, à lastatic
durée de vie, où une variable dure "pour toujours", quelle que soit la portée.auto
est la durée de vie par défaut, et n'est presque jamais explicite. C'est pourquoi il était prudent de changer le sensC++
.Désormais
C
, avant la norme 99, si vous ne spécifiez pas le type d'une variable, la valeur par défaut estint
.Donc, avec
auto a = 1;
vous déclarez (et définissez) uneint
variable, avec une durée de vie déterminée par la portée.(«durée de vie» est plus correctement appelée «durée de stockage», mais je pense que c'est peut-être moins clair).
la source
main
fonction".auto
et cestatic
sont les deux seules possibilités. J'essayais d'écrire ma réponse d'une manière ciblée sur le demandeur, qui semble être assez nouveau pourC++
(etC
), alors j'ai un peu passé sous silence les détails. C'était peut-être une mauvaise idée; ils doivent être couverts tôt ou tard.int
truc implicite est supprimé de C depuis 1999.En C, et les dialectes historiques de C ++, il
auto
y a un mot-clé signifiant quia
a un stockage automatique. Comme il ne peut être appliqué qu'aux variables locales, qui sont automatiques par défaut, personne ne l'utilise; c'est pourquoi 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
. Cette déclaration équivaut donc àJe pense que c'est déconseillé (et peut-être interdit) dans le C moderne; mais certains compilateurs populaires utilisent par défaut C90 (ce qui, je pense, le permet), et, ce qui est ennuyeux, n'active les avertissements que si vous les demandez spécifiquement. Compiler avec GCC et spécifier C99 avec
-std=c99
, ou activer l'avertissement avec-Wall
ou-Wimplicit-int
, donne un avertissement:la source
En C, cela
auto
signifie la même choseregister
en C ++ 11: cela signifie qu'une variable a une durée de stockage automatique.Et dans C avant C99 (et le compilateur de Microsoft ne prend en charge ni C99 ni C11, bien qu'il puisse en prendre en charge 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.
la source
auto
etregister
avait exactement la même signification (j'ai déjà commenté qu'il y avait des restrictions sur la priseregister
d'adresse d' une variable qualifiée, mais c'était incorrect pour C ++).register
, bien que obsolète, conserve son ancienne signification pour le moment.auto
C signifie la même chose qu'enregister
C ++, ce qu'il fait (les deux signifient la durée de stockage automatique, et rien d'autre).Le type de compilation Visual Studio est disponible sur
right click on file -> Properties -> C/C++ -> Advanced -> Compile As
. Pour s'assurer qu'il est compilé comme/TC
option force C. Dans ce cas, c'est ce que dit larsmans (ancienauto
mot-clé C ). Il peut être compilé en C ++ sans que vous le sachiez.la source
Une classe de stockage définit la portée (visibilité) et la durée de vie des variables et / ou des fonctions au sein d'un programme C.
Les classes de stockage suivantes peuvent être utilisées dans un programme C
auto
est la classe de stockage par défaut pour toutes les variables locales.L'exemple ci-dessus définit deux variables avec la même classe de stockage. auto ne peut être utilisé que dans des fonctions, c'est-à-dire des variables locales.
int
est le type par défaut pour leauto
code ci-dessous:Le code ci-dessous est également légal:
la source