Où le mot-clé C auto est-il utilisé?

104

Pendant mes années à l'université, j'ai lu sur le automot - clé et au fil du temps, j'ai en fait oublié ce que c'était. Il est défini comme:

définit une variable locale comme ayant une durée de vie locale

Je n'ai jamais trouvé qu'il était utilisé nulle part, est-il vraiment utilisé et si oui, où est-il utilisé et dans quels cas?

Vijay
la source

Réponses:

90

autoest un modificateur comme static. Il définit la classe de stockage d'une variable. Cependant, étant donné que la valeur par défaut pour les variables locales est auto, vous n'avez normalement pas besoin de la spécifier manuellement.

Cette page répertorie les différentes classes de stockage en C.

Mehrdad Afshari
la source
13
J'étais juste en train de revoir cela après que quelqu'un ait voté ma réponse. Vous dites que vous n'avez normalement pas besoin de le spécifier manuellement. Je dois juste demander: y a-t-il réellement une circonstance dans laquelle auto peut être spécifiée mais ne se produira pas par défaut?
Jerry Coffin
2
@JerryCoffin Pas en C. En C ++ 11, il est réutilisé et vous pouvez l'utiliser pour obtenir efficacement l'inférence de type de variable locale.
Mehrdad Afshari
2
Une utilisation possible est la déclaration directe de fonctions imbriquées dans GNU C - bien qu'il s'agisse d'un détournement de la définition originale de auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah
2
La page liée est obsolète. Depuis C11, il y a aussi des _Thread_localdétails: en.cppreference.com/w/c/language/storage_duration et stackoverflow.com/a/14289720/6557621
MCCCS
132

Si vous lisez la liste IAQ (Questions non posées), vous savez que l'automobile est principalement utile pour définir ou déclarer un véhicule:

auto my_car;

Un véhicule constamment stationné à l'extérieur:

extern auto my_car;

Pour ceux qui n'ont aucun sens de l'humour et qui veulent «juste les faits Madame»: la réponse courte est qu'il n'y a jamais aucune raison d'utiliser autodu tout. Le seul moment où vous êtes autorisé à utiliser autoest avec une variable qui a déjà autoune classe de stockage, donc vous spécifiez simplement quelque chose qui se produirait de toute façon. Tenter d'utiliser autosur une variable qui n'a pas déjà la autoclasse de stockage entraînera le rejet de votre code par le compilateur. Je suppose que si vous voulez devenir technique, votre implémentation n'a pas besoin d'être un compilateur (mais c'est le cas) et elle peut théoriquement continuer à compiler le code après avoir émis un diagnostic (mais ce ne sera pas le cas).

Petit addendum par kaz :

Il y a aussi:

static auto my_car;

ce qui nécessite un diagnostic selon ISO C. C'est correct, car il déclare que la voiture est en panne. Le diagnostic est gratuit, mais éteindre la lumière du tableau de bord vous coûtera quatre-vingts dollars. (Vingt ou moins, si vous achetez votre propre clé USB pour les diagnostics embarqués sur eBay).

Ce qui précède extern auto my_carnécessite également un diagnostic, et pour cette raison, il n'est jamais exécuté par le compilateur, sauf par le personnel de la ville chargé de l'application du stationnement.

Si vous en voyez beaucoup extern static auto ...dans n'importe quelle base de code, vous êtes dans un mauvais quartier; cherchez un meilleur travail immédiatement, avant que tout l'endroit ne se transforme en Rust.

Jerry Coffin
la source
@self .: L'ISO ne semble pas connaître une "ISO 2011". Que pensez-vous que cela pourrait normaliser?
Jerry Coffin
6
C'est une bonne chose que je n'ai pas eu de café, de cola, de stout ou d'un autre liquide de couleur sombre dans la bouche. Tu me devrais un écran d'ordinateur, @JerryCoffin, si c'était le cas. MEILLEURE RÉPONSE JAMAIS!
David Hammen
2
@Dan: Honnêtement, il vous a fallu "un certain temps" pour lire 5 lignes de texte et obtenir la partie où il est dit: "La réponse courte est qu'il n'y a jamais aucune raison d'utiliser l'auto du tout"? Sérieusement? Compte tenu du commentaire qui précède immédiatement le vôtre, il semble qu'au moins quelques personnes y trouvent une contribution positive.
Jerry Coffin
@JerryCoffin J'ai déjà expliqué cela, relisez mon commentaire. Le recul est de 20/20.
Dan Bechard
2
J'ai récemment passé une grave conflagration (fermé deux voies) qui suggère un besoin dechar auto my_car;
austère
46

Le automot-clé est inutile dans le langage C. Il est là parce qu'avant le langage C il existait un langage B dans lequel ce mot-clé était nécessaire pour déclarer des variables locales. (B a été développé en NB, qui est devenu C).

Voici le manuel de référence B .

Comme vous pouvez le voir, le manuel regorge d'exemples dans lesquels il autoest utilisé. Il en est ainsi car il n'y a pas de intmot-clé. Une sorte de mot-clé est nécessaire pour dire "ceci est une déclaration d'une variable", et ce mot-clé indique également s'il s'agit d'un mot-clé local ou externe ( autoversus extrn). Si vous n'utilisez pas l'un ou l'autre, vous avez une erreur de syntaxe. C'est-à-dire, ce x, y;n'est pas une déclaration en soi, mais auto x, y;c'est.

Étant donné que les bases de code écrites en B devaient être portées vers NB et vers C au fur et à mesure que le langage était développé, les versions plus récentes du langage emportaient des bagages pour une compatibilité ascendante améliorée qui se traduisait par moins de travail. Dans le cas de auto, les programmeurs n'avaient pas à rechercher chaque occurrence de autoet à la supprimer.

Il est évident d'après le manuel que le cruft maintenant obsolescent "implicit int" en C (pouvoir écrire main() { ... }sans aucun intdevant) vient aussi de B. C'est une autre fonctionnalité de compatibilité descendante pour supporter le code B. Les fonctions n'ont pas de type de retour spécifié dans B car il n'y a aucun type. Tout est un mot, comme dans de nombreux langages d'assemblage.

Notez comment une fonction peut simplement être déclarée extrn putcharet ensuite la seule chose qui en fait une fonction que cet identifiant utilise : elle est utilisée dans une expression d'appel de fonction comme putchar(x), et c'est ce qui indique au compilateur de traiter ce mot sans type comme un pointeur de fonction.

Kaz
la source
24

En C autoest un mot-clé qui indique qu'une variable est locale à un bloc. Étant donné que c'est la valeur par défaut pour les variables à portée de bloc, il est inutile et très rarement utilisé (je ne pense pas l'avoir jamais vu utiliser en dehors des exemples dans des textes qui traitent du mot-clé). Je serais intéressé si quelqu'un pouvait signaler un cas où l'utilisation de autoétait nécessaire pour obtenir une analyse ou un comportement correct.

Cependant, dans la norme C ++ 11, le automot - clé a été `` détourné '' pour prendre en charge l'inférence de type, où le type d'une variable peut être extrait du type de son initialiseur:

auto someVariable = 1.5;   // someVariable will have type double

L'inférence de type est ajoutée principalement pour prendre en charge la déclaration de variables dans des modèles ou renvoyée à partir de fonctions de modèle où les types basés sur un paramètre de modèle (ou déduits par le compilateur lorsqu'un modèle est instancié) peuvent souvent être assez pénibles à déclarer manuellement.

Michael Burr
la source
1
«La variable est locale à un bloc» - ce n'est pas du tout vrai. Toutes les variables déclarées dans un bloc sont locales à ce bloc (par rapport à la portée). Ils peuvent être liés à d'autres variables du programme, mais la déclaration n'est visible que dans ce bloc. autoconcerne la classe de stockage qui n'a rien à voir avec la visibilité.
fuz le
12

Avec l'ancien compilateur Aztec C, il était possible de transformer toutes les variables automatiques en variables statiques (pour une vitesse d'adressage accrue) à l'aide d'un commutateur de ligne de commande.

Mais les variables explicitement déclarées avec autoont été laissées telles quelles dans ce cas. (Un must pour les fonctions récursives qui autrement ne fonctionneraient pas correctement!)

raphnet
la source
7

Le automot-clé est similaire à l'inclusion de points-virgules dans Python, il était requis par un langage précédent ( B) mais les développeurs ont réalisé qu'il était redondant car la plupart des choses l'étaient auto.

Je soupçonne qu'il a été laissé pour aider à la transition de B à C. En bref, une utilisation est pour la compatibilité du langage B.

Par exemple en B et 80s C:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}
Mikhail
la source
1

Le mot clé automatique est un exemple de classe de stockage (une sorte de techniques qui décide de la durée de vie de la variable et du lieu de stockage). Il a un comportement selon lequel la variable créée par l'aide de ce mot-clé a une durée de vie (durée de vie) uniquement entre les accolades

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          
Atul Sharma
la source
1

autone peut être utilisé que pour les variables de type bloc. extern auto intest nul parce que le compilateur ne peut pas déterminer si cela utilise une définition externe ou s'il faut remplacer l'extern avec une définition automatique (également auto et extern sont des durées de stockage entièrement différentes, comme static auto int, ce qui est aussi évidemment nul). Il peut toujours choisir de l'interpréter dans un sens, mais choisit plutôt de le traiter comme une erreur.

Il y a une fonctionnalité qui autofournit et qui active la règle «tout est un int» à l'intérieur d'une fonction. Contrairement à l'extérieur d'une fonction, où a=3est interprété comme une définition int a =3car les affectations n'existent pas dans la portée du fichier, a=3est une erreur à l'intérieur d'une fonction car apparemment le compilateur l'interprète toujours comme une affectation à une variable externe plutôt qu'une définition (même s'il y a n'y a pas de extern int adéclarations anticipées dans la fonction ou dans le champ de fichier), mais un prescripteur comme static, const, volatileou autoimpliquerait qu'il est une définition et le compilateur qu'il prend comme une définition, à l' exception auton'a pas les effets secondaires des autres spécificateurs. auto a=3est donc implicitement auto int a = 3. Certes,signed a = 3a le même effet et unsigned a = 3est toujours un entier non signé.

Notez également que ' auton'a aucun effet sur l'affectation d'un objet à un registre (à moins qu'un compilateur particulier n'y prête attention, mais cela semble peu probable)'

Lewis Kelsey
la source
-1

Je suis sûr que vous êtes familier avec les spécificateurs de classe de stockage en C qui sont "extern", "static", "register" et "auto". La définition de «auto» est à peu près donnée dans d'autres réponses mais voici une utilisation possible du mot-clé «auto» dont je ne suis pas sûr, mais je pense que cela dépend du compilateur. Vous voyez, en ce qui concerne les spécificateurs de classe de stockage, il existe une règle. Nous ne pouvons pas utiliser plusieurs spécificateurs de classe de stockage pour une variable. C'est pourquoi les variables globales statiques ne peuvent pas être externalisées. Par conséquent, ils ne sont connus que de leur dossier. Lorsque vous accédez aux paramètres de votre compilateur, vous pouvez activer l'indicateur d'optimisation pour la vitesse. l'une des façons dont le compilateur optimise est, il recherche des variables sans spécificateurs de classe de stockage, puis effectue une évaluation en fonction de la disponibilité de la mémoire cache et de certains autres facteurs pour voir s'il doit traiter cette variable à l'aide du spécificateur de registre ou non. Maintenant, que se passe-t-il si nous voulons optimiser notre code pour la vitesse tout en sachant qu'une variable spécifique dans notre programme n'est pas très importante et que nous ne voulons même pas que le compilateur la considère comme un registre. Cependant, en mettant auto, le compilateur sera incapable d'ajouter un spécificateur de registre à une variable depuis la saisie de "register auto int a;" OU "enregistrement automatique int a;" soulève l'erreur d'utiliser plusieurs spécificateurs de classe de stockage. Pour résumer, je pensais que l'auto pouvait empêcher le compilateur de traiter une variable comme un registre via l'optimisation. et si nous voulons optimiser notre code pour la vitesse tout en sachant qu'une variable spécifique dans notre programme n'est pas très importante et que nous ne voulons même pas que le compilateur la considère comme un registre. Cependant, en mettant auto, le compilateur sera incapable d'ajouter un spécificateur de registre à une variable depuis la saisie de "register auto int a;" OU "enregistrement automatique int a;" soulève l'erreur d'utiliser plusieurs spécificateurs de classe de stockage. Pour résumer, je pensais que l'auto pouvait empêcher le compilateur de traiter une variable comme un registre via l'optimisation. et si nous voulons optimiser notre code pour la vitesse tout en sachant qu'une variable spécifique dans notre programme n'est pas très importante et que nous ne voulons même pas que le compilateur la considère comme un registre. Cependant, en mettant auto, le compilateur sera incapable d'ajouter un spécificateur de registre à une variable depuis la saisie de "register auto int a;" OU "enregistrement automatique int a;" soulève l'erreur d'utiliser plusieurs spécificateurs de classe de stockage. Pour résumer, je pensais que l'auto pouvait empêcher le compilateur de traiter une variable comme un registre via l'optimisation. soulève l'erreur d'utiliser plusieurs spécificateurs de classe de stockage. Pour résumer, je pensais que l'auto pouvait empêcher le compilateur de traiter une variable comme un registre via l'optimisation. soulève l'erreur d'utiliser plusieurs spécificateurs de classe de stockage. Pour résumer, je pensais que l'auto pouvait empêcher le compilateur de traiter une variable comme un registre via l'optimisation.

Cette théorie n'a pas fonctionné pour le compilateur GCC mais je n'ai pas essayé d'autres compilateurs.

Alireza Mirghasemi
la source