web-dev-qa-db-fra.com

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

Remarque cette question a été publiée pour la première fois en 2009, avant la ratification de C++ 11 et avant la modification radicale du mot clé auto. Les réponses fournies concernent only au sens C++ 03 de auto - qu’il s’agit d’une classe de stockage spécifiée - et non au sens C++ 11 de auto - qui est une déduction de type automatique. Si vous recherchez des conseils sur l'utilisation de C++ 11 auto, cette question ne vous concerne pas.

Pendant très longtemps, j'ai pensé qu'il n'y avait aucune raison d'utiliser le mot clé static en C, car les variables déclarées en dehors de block-scope étaient implicitement globales. Ensuite, j'ai découvert que déclarer une variable comme étant static dans block-scope lui donnerait une durée permanente, et le déclarer en dehors de block-scope (dans program-scope) lui donnerait file-scope (accessible uniquement dans cette unité de compilation).

Cela ne me laisse donc qu’un mot-clé que je ne comprends peut-être pas encore parfaitement: le mot-clé auto. Existe-t-il une autre signification que celle de «variable locale»? Tout ce qu'il fait qui ne soit pas implicitement fait pour vous où que vous souhaitiez l'utiliser? Comment une variable auto se comporte-t-elle dans la portée du programme? Qu'en est-il d'une variable static auto dans la portée du fichier? Ce mot-clé a-t-il un but autre que simplement existant pour être complet?

84
Carson Myers

auto est également un spécificateur de classe de stockage, static, register et extern. Vous ne pouvez utiliser que l'un de ces quatre éléments 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 auto devant eux est redondant car c’est le cas par défaut. 

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

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

Pour la rendre syntaxe valide ou la lever de l’ambiguïté d’une expression d’affectation si i est dans la portée. Mais cela ne fonctionne quand même pas en C++ (vous devez spécifier un type). Assez drôle, le standard C++ écrit:

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

qui fait référence au scénario suivant, qui peut être une conversion de a en int ou la déclaration d'une variable a de type int avec des parenthèses redondantes autour de a. Cela est toujours considéré comme une déclaration, donc auto n’ajouterait rien d’utile ici, mais le ferait pour l’humain. Mais encore une fois, il serait préférable que l’humain enlève les parenthèses redondantes autour de a, je dirais:

int(a);

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

74

Dans C++ 11, auto a une nouvelle signification: il vous permet de déduire automatiquement le type d'une variable.

Pourquoi est-ce utile? Considérons un exemple de base:

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

La auto crée un itérateur de type std::list<int>::iterator.

Cela peut rendre un code sérieusement complexe beaucoup plus facile à lire.

Un autre exemple:

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

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

86
std''OrgnlDave

Le mot clé auto n'a pas de raison pour le moment. Vous avez tout à fait raison de rappeler la classe de stockage par défaut d'une variable locale, l'alternative vraiment utile étant static.

Il a une nouvelle signification en C++ 0x. Cela vous donne une idée de l’inefficacité!

34
Daniel Earwicker

GCC a une utilisation particulière de auto pour 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.

7
qrdl

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

3
T.E.D.

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'une routine de service d'interruption) . 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;

Le mot clé auto aide donc à documenter l'intention.

3
luke

Selon Stroustrup, dans "Le langage de programmation C" (4e édition, couvrant C 11), l'utilisation de "auto" a les principales raisons suivantes (section 2.2.2) (les mots de Stroustrup sont cités):

1) 

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

Avec 'auto' et son initialiseur nécessaire, vous pouvez 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 ressemble à 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 type 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;
}
2
wesley.mesquita

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

1
chaz

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

La conférence mérite d'être visionnée dans son intégralité, mais la partie concernant le mot-clé auto se situe autour de la 29e minute (environ).

1
Sabuncu

Existe-t-il une autre signification pour "auto" autre que "variable locale?"  

Pas en C++ 03.

Tout ce qu'il fait qui ne soit 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 du fichier?  

Mot clé non autorisé en dehors d'un corps de fonction/méthode.

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

Étonnamment, oui. Les critères de conception C++ incluaient un degré élevé de compatibilité ascendante avec C. Ce mot clé était associé à C et il n'existait 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 une utilité en C autre que celle d'exister simplement pour être complet?

J'en ai appris un 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 consistait à spécifier son type de stockage (auto ou 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, int. J'imagine que chaque programme créé en B et porté en C était littéralement rempli de variables auto à cette époque.

C++ 03 n'autorise plus le type implicite int du style C, mais il conserve le mot clé auto, qui n'est plus très utile, car contrairement à l'int implicite, il n'était pas connu pour causer de problèmes dans la syntaxe de C.

0
Jirka Hanika