Y a-t-il une raison d'utiliser le mot clé 'auto' en C ++ 03?

85

Notez que cette question a été publiée à l'origine en 2009, avant la ratification de C ++ 11 et avant que la signification du automot - clé ne soit radicalement modifiée. Les réponses fournies concernent uniquement la signification C ++ 03 de auto- qui est une classe de stockage spécifiée - et non la signification C ++ 11 de auto- c'est-à-dire la déduction automatique de type. Si vous recherchez des conseils sur l'utilisation du C ++ 11 auto, cette question n'est pas pertinente pour cette question.

Pendant très longtemps, j'ai pensé qu'il n'y avait aucune raison d'utiliser le staticmot - clé en C, car les variables déclarées en dehors de la portée du bloc étaient implicitement globales. Ensuite, j'ai découvert que déclarer une variable comme staticdans la portée du bloc lui donnerait une durée permanente, et la déclarer en dehors de la portée du bloc (dans la portée du programme) lui donnerait une portée fichier (accessible uniquement dans cette unité de compilation).

Cela me laisse donc avec un seul mot-clé que je ne comprends (peut-être) pas encore complètement: le automot-clé. Y a-t-il une autre signification que «variable locale»? Tout ce qu'il fait qui n'est pas implicitement fait pour vous où que vous souhaitiez l'utiliser? Comment une autovariable se comporte-t-elle dans la portée du programme? Qu'en est-il d'une static autovariable dans la portée du fichier? Ce mot-clé a-t-il un autre objectif que d' exister simplement pour être complet ?

Carson Myers
la source

Réponses:

74

autoest un spécificateur de classe de stockage static, registeret externaussi. Vous ne pouvez utiliser que l'un de ces quatre dans une déclaration.

Les variables locales (sans static) ont une durée de stockage automatique, ce qui signifie qu'elles vivent du début de leur définition jusqu'à la fin de leur bloc. Mettre l'auto devant eux est redondant puisque c'est de toute façon la valeur par défaut.

Je ne connais aucune raison de l'utiliser en C ++. Dans les anciennes versions C qui ont la règle implicite int, vous pouvez l'utiliser pour déclarer une variable, comme dans:

int main(void) { auto i = 1; }

Pour rendre la syntaxe valide ou lever l'ambiguïté d'une expression d'affectation au cas où elle iserait dans la portée. Mais cela ne fonctionne pas en C ++ de toute façon (vous devez spécifier un type). Assez drôle, le standard C ++ écrit:

Un objet déclaré sans spécificateur de classe de stockage à la portée de bloc ou déclaré en tant que paramètre de fonction a une durée de stockage automatique par défaut. [Remarque: par conséquent, le spécificateur automatique est presque toujours redondant et pas souvent utilisé; une utilisation de auto est de distinguer explicitement une déclaration-instruction d'une expression-instruction (6.8). - note de fin]

qui fait référence au scénario suivant, qui pourrait être soit une conversion de ato, intsoit la déclaration d'une variable ade type intayant des parenthèses redondantes autour a. Il est toujours considéré comme une déclaration, donc auton'ajouterait rien d'utile ici, mais le ferait pour l'humain, à la place. Mais là encore, l'humain ferait mieux de supprimer les parenthèses redondantes a, je dirais:

int(a);

Avec la nouvelle signification d' autoarriver avec C ++ 0x, je découragerais de l'utiliser avec la signification de C ++ 03 dans le code.

Johannes Schaub - litb
la source
4
Les compilateurs C ++ avaient souvent l'habitude d'avoir un int implicite pour les valeurs de retour des fonctions, dans les jours ARM avant la norme ... Avant l'EMPIRE ...
Daniel Earwicker
1
Je viens de le reconnaître comme la façon dont mes compilateurs me disent que j'ai oublié de déclarer une fonction en avant. Cela me dirait que mon utilisation d'une fonction était différente de la façon dont elle a été déclarée en raison d'un int implicite.
Carson Myers
29
La meilleure partie est que les programmeurs avaient l'habitude d'écrire "auto" (quatre lettres) pour éviter d'écrire "int" (trois lettres).
Max Lybbert
30
@Max - hé, beaucoup de gens disent "double-u-double-u-double-u" comme une abréviation de "World Wide Web".
Daniel Earwicker
3
@smichak non, "volatile" est un qualificatif de type. Plutôt que de déterminer où stocker une valeur, il modifie le comportement d'une écriture vers et d'une lecture à partir d'un objet de type qualifié volatile. Il peut y avoir des variables de pile qualifiées volatiles (classe de stockage automatique) ainsi que des variables de durée de stockage statiques qualifiées volatiles (classe de stockage «statique» locale, variables non locales). A part ça, je ne sais pas si "register volatile" est une combinaison valide :)
Johannes Schaub - litb
86

En C ++ 11, autoa un nouveau sens: il permet de déduire automatiquement le type d'une variable.

Pourquoi est-ce jamais utile? Prenons un exemple basique:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

Le autolà crée un itérateur de type std::list<int>::iterator.

Cela peut rendre certains codes très complexes beaucoup plus faciles à lire.

Un autre exemple:

int x, y;
auto f = [&]{ x += y; };
f();
f();

Là, on a autodéduit le type requis pour stocker une expression lambda dans une variable. Wikipedia a une bonne couverture sur le sujet.

std''OrgnlDave
la source
4
Je ne sais toujours pas si c'est une bonne utilisation de l'automobile. Le code doit être facile à lire, pas facile à écrire!
DanDan le
38
Je ne sais pas pour vous mais je trouve cela beaucoup plus facile à lire que le spam de type itérateur.
Overv
17
Et si, pour une raison quelconque, vous décidez de changer de classe de la liste <int> à une autre classe, vous n'avez pas à rechercher chaque déclaration d'itérateur et à la changer.
roslav
2
@KarateSnowMachine: Si vous vouliez le const, vous utiliseriez "const auto" au lieu de "auto".
darth happyface
4
@darth const auto it = a.begin();vous donnerait un const iterator, pas un const_iterator. Vous devriez toujours changer l'élément, mais échoueriez ++ità compiler. Pour obtenir un const_iterator, vous utiliseriezauto it = a.cbegin();
fredoverflow
35

Le mot-clé auto n'a pour l'instant aucun but. Vous avez parfaitement raison de dire que cela ne fait que reformuler la classe de stockage par défaut d'une variable locale, l'alternative vraiment utile étant static.

Il a une toute nouvelle signification en C ++ 0x. Cela vous donne une idée de combien c'était inutile!

Daniel Earwicker
la source
1
oh mec, est-ce toujours inutile. J'aime le nouveau sens cependant. Cela rend certains codes beaucoup moins verbeux et redondants.
Carson Myers
Oui, après avoir utilisé l'équivalent en C #, cela fera probablement une énorme différence. Plus encore en C ++ si vous utilisez des modèles d'expression où les types sont si complexes qu'ils n'ont jamais été destinés à être écrits à la main.
Daniel Earwicker
7

GCC a une utilisation spéciale autopour les fonctions imbriquées - voir ici .

Si vous avez une fonction imbriquée que vous souhaitez appeler avant sa définition, vous devez la déclarer avec auto.

qrdl
la source
c'est une excellente implémentation d'auto, bien que dépendante du compilateur. Merci pour la recherche :)
Carson Myers
3

"auto" dit supposément au compilateur de décider par lui-même où placer la variable (mémoire ou registre). Son analogue est "register", qui dit supposément au compilateur d'essayer de le garder dans un registre. Les compilateurs modernes ignorent les deux, vous devriez donc aussi.

TED
la source
1
Pas exactement - si vous le déclarez avec "register", les compilateurs ne vous permettent pas d'utiliser l'opérateur address-of (& foo) sur la variable parce que, eh bien, il n'existe nulle part en mémoire (et n'a donc pas d'adresse).
Tim Čas
3

J'utilise ce mot-clé pour documenter explicitement quand il est essentiel pour la fonction, que la variable soit placée sur la pile, pour les processeurs basés sur la pile. Cette fonction peut être requise lors de la modification de la pile avant de revenir d'une fonction (ou d'interrompre la routine de service). Dans ce cas, je déclare:

auto unsigned int auiStack[1];   //variable must be on stack

Et puis j'accède en dehors de la variable:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

Ainsi, le automot - clé aide à documenter l'intention.

Luke
la source
Je suppose qu'il ne s'agit que d'une intention de signalisation, car le mot clé n'applique pas réellement le placement de la pile, pas plus que de simplement l'omettre.
underscore_d
2

Selon Stroustrup, dans "The C Programming Language" (4e édition, couvrant C 11), l'utilisation de 'auto' a les raisons majeures suivantes (section 2.2.2) (les mots Stroustrup sont cités):

1)

La définition est dans une large portée où nous voulons rendre le type clairement visible aux lecteurs de notre code.

Avec 'auto' et son initialiseur nécessaire, nous pouvons connaître le type de la variable en un coup d'œil!

2)

Nous voulons être explicites sur la plage ou la précision de la variable (par exemple, double plutôt que float)

À mon avis, un cas qui convient ici, est quelque chose comme ceci:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

En utilisant 'auto', nous évitons la redondance et l'écriture de noms de types longs.

Imaginez un nom de type long à partir d'un itérateur basé sur un modèle:

(code de la section 6.3.6.1)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}
wesley.mesquita
la source
1

Dans l'ancien compilateur, auto était un moyen de déclarer une variable locale. Vous ne pouvez pas déclarer de variables locales dans d'anciens compilateurs comme Turbo C sans le mot clé auto ou un autre.

chaz
la source
1

La nouvelle signification du mot-clé auto dans C ++ 0x est très bien décrite par Stephan T. Lavavej de Microsoft dans une conférence vidéo librement consultable / téléchargeable sur STL trouvée sur le site Channel 9 de MSDN ici .

La conférence vaut la peine d'être visionnée dans son intégralité, mais la partie sur le mot-clé auto est à environ la 29e minute (environ).

Sabuncu
la source
0

Y a-t-il un autre sens à «auto» que «variable locale»?

Pas en C ++ 03.

Tout ce qu'il fait qui n'est pas implicitement fait pour vous où que vous souhaitiez l'utiliser?

Rien du tout, en C ++ 03.

Comment une variable automatique se comporte-t-elle dans la portée du programme? Qu'en est-il d'une variable automatique statique dans la portée de fichier?

Mot clé non autorisé en dehors du corps d'une fonction / méthode.

Ce mot clé a-t-il un but [en C ++ 03] autre que d'exister simplement pour être complet?

Étonnamment, oui. Les critères de conception C ++ incluaient un degré élevé de compatibilité descendante avec C. C avait ce mot-clé et il n'y avait aucune raison réelle de l'interdire ou de redéfinir sa signification en C ++. Donc, le but était une incompatibilité de moins avec C.

Ce mot-clé a-t-il un but en C autre que d'exister simplement pour être complet?

J'en ai appris une récemment: la facilité de portage d'anciens programmes de B. C a évolué à partir d'un langage appelé B dont la syntaxe était assez similaire à celle de C. Cependant, B n'avait aucun type. La seule façon de déclarer une variable dans B était de spécifier son type de stockage ( autoou extern). Comme ça:

auto i;

Cette syntaxe fonctionne toujours en C et équivaut à

int i;

car en C, la classe de stockage par défaut est auto, et le type par défaut est int. J'imagine que chaque programme provenant de B et porté en C était littéralement plein de autovariables à l'époque.

C ++ 03 n'autorise plus le style C implicite int, mais il a conservé le automot clé no-longer-exactement-utile car contrairement à l'int implicite, il n'était pas connu pour causer des problèmes dans la syntaxe de C.

Jirka Hanika
la source