C'è qualche motivo per utilizzare la parola chiave "auto" in C ++ 03?


85

Nota che questa domanda è stata originariamente pubblicata nel 2009, prima che C ++ 11 fosse ratificato e prima che il significato della autoparola chiave fosse cambiato drasticamente. Le risposte fornite riguardano solo il significato C ++ 03 di auto- che è una classe di archiviazione specificata - e non il significato C ++ 11 di auto- che è deduzione automatica del tipo. Se stai cercando consigli su quando usare il C ++ 11 auto, questa domanda non è rilevante per quella domanda.

Per molto tempo ho pensato che non ci fosse motivo di usare la staticparola chiave in C, perché le variabili dichiarate al di fuori dell'ambito del blocco erano implicitamente globali. Poi ho scoperto che dichiarare una variabile come staticall'interno dell'ambito del blocco gli darebbe una durata permanente, e dichiararla al di fuori dell'ambito del blocco (nell'ambito del programma) gli darebbe l'ambito del file (è possibile accedervi solo in quell'unità di compilazione).

Quindi questo mi lascia con una sola parola chiave che (forse) non comprendo ancora completamente: la autoparola chiave. C'è qualche altro significato oltre a "variabile locale"? Qualcosa che non viene fatto implicitamente per te ovunque tu voglia usarlo? Come si comporta una autovariabile nell'ambito del programma? Che dire di una static autovariabile nell'ambito del file? Questa parola chiave ha uno scopo diverso dal semplice esistere per completezza ?

Risposte:


74

autoè un identificatore di classe di archiviazione, static, registere externanche. Puoi usare solo uno di questi quattro in una dichiarazione.

Le variabili locali (senza static) hanno una durata di memorizzazione automatica, il che significa che vivono dall'inizio della loro definizione fino alla fine del loro blocco. Mettere auto davanti a loro è ridondante poiché è comunque l'impostazione predefinita.

Non conosco alcun motivo per usarlo in C ++. Nelle vecchie versioni C che hanno la regola int implicita, potresti usarla per dichiarare una variabile, come in:

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

Per rendere valida la sintassi o disambiguare un'espressione di assegnazione nel caso in cui isia nell'ambito. Ma questo non funziona comunque in C ++ (devi specificare un tipo). Abbastanza divertente, lo standard C ++ scrive:

Un oggetto dichiarato senza un identificatore di classe di archiviazione nell'ambito del blocco o dichiarato come parametro di funzione ha una durata di archiviazione automatica per impostazione predefinita. [Nota: quindi, lo specificatore automatico è quasi sempre ridondante e non viene utilizzato spesso; un uso di auto è distinguere esplicitamente una dichiarazione-dichiarazione da un'istruzione-espressione (6.8). - nota finale]

che si riferisce al seguente scenario, che potrebbe essere un cast di ato into la dichiarazione di una variabile adi tipo intcon parentesi ridondanti intorno a. È sempre considerata una dichiarazione, quindi autonon aggiungerei nulla di utile qui, ma lo farebbe invece per l'umano. Ma poi di nuovo, l'umano farebbe meglio a rimuovere le parentesi ridondanti intorno a, direi:

int(a);

Con il nuovo significato di autoarrivare con C ++ 0x, sconsiglierei di usarlo con il significato di C ++ 03 nel codice.


4
I compilatori C ++ spesso avevano un int implicito per i valori di ritorno dalle funzioni, nei giorni ARM prima dello standard ... Before the EMPIRE ...
Daniel Earwicker

1
L'ho appena riconosciuto come il modo in cui i compilatori mi dicono che ho dimenticato di dichiarare in avanti una funzione. Mi direbbe che il mio utilizzo di una funzione era diverso dal modo in cui è stato dichiarato a causa di int implicito.
Carson Myers

29
La parte migliore è che i programmatori scrivevano "auto" (quattro lettere) per evitare di scrivere "int" (tre lettere).
Max Lybbert,

30
@ Max - ehi, molte persone dicono "double-u-double-u-double-u" come abbreviazione di "World Wide Web".
Daniel Earwicker,

3
@smichak no, "volatile" è un qualificatore di tipo. Piuttosto che determinare dove memorizzare un valore, modifica il comportamento di scrittura e lettura da un oggetto del tipo qualificato volatile. Possono essere presenti variabili di stack qualificate volatili (classe di memorizzazione automatica) e variabili di durata della memorizzazione statica qualificata volatili (classe di memorizzazione "statica" locale, variabili non locali). A parte questo, non so se "registro volatile" sia una combinazione valida :)
Johannes Schaub - litb

86

In C ++ 11 autoha un nuovo significato: permette di dedurre automaticamente il tipo di una variabile.

Perché è mai utile? Consideriamo un esempio di base:

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

Il autothere crea un iteratore di tipo std::list<int>::iterator.

Questo può rendere molto più facile leggere del codice molto complesso.

Un altro esempio:

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

Lì, ha autodedotto il tipo richiesto per memorizzare un'espressione lambda in una variabile. Wikipedia ha una buona copertura sull'argomento.


4
Non sono ancora sicuro che sia un ottimo uso dell'auto. Il codice dovrebbe essere facile da leggere, non facile da scrivere!
DanDan

38
Non so voi ma trovo questo molto più facile da leggere rispetto allo spam di tipo iteratore.
Overv

17
E se per qualche risonanza decidi di cambiare classe da list <int> a qualche altra classe, non devi cercare ogni dichiarazione di iteratore e cambiarla.
roslav

2
@KarateSnowMachine: Se volessi const, useresti "const auto" invece di "auto".
darth happyface

4
@darth const auto it = a.begin();ti darebbe un const iterator, non un const_iterator. Potresti comunque cambiare l'elemento, ma ++itnon riusciresti a compilare. Per ottenere un const_iterator, dovresti usareauto it = a.cbegin();
fredoverflow

35

La parola chiave auto non ha scopo al momento. Hai esattamente ragione che ribadisce solo la classe di archiviazione predefinita di una variabile locale, l'alternativa davvero utile è static.

Ha un significato nuovo di zecca in C ++ 0x. Questo ti dà un'idea di quanto fosse inutile!


1
oh amico, è mai inutile. Mi piace però il nuovo significato. Rende un po 'di codice molto meno prolisso e ridondante.
Carson Myers

Sì, avendo usato l'equivalente in C # probabilmente farà un'enorme differenza. Ancora di più in C ++ se utilizzi modelli di espressioni in cui i tipi sono così complessi da non essere mai stati concepiti per essere scritti a mano.
Daniel Earwicker,

7

GCC ha un uso speciale di autoper le funzioni annidate - vedi qui .

Se si dispone di una funzione annidata che si desidera chiamare prima della sua definizione, è necessario dichiararla con auto.


questa è una grande implementazione, sebbene dipendente dal compilatore, di auto. Grazie per la ricerca :)
Carson Myers

3

"auto" presumibilmente dice al compilatore di decidere da solo dove mettere la variabile (memoria o registro). Il suo analogo è "register", che presumibilmente dice al compilatore di provare a tenerlo in un registro. I compilatori moderni ignorano entrambi, quindi dovresti farlo anche tu.


1
Non esattamente - se lo dichiari con "register", i compilatori non ti permettono di usare l'operatore address-of (& foo) sulla variabile perché, beh, non esiste da nessuna parte in memoria (e quindi non ha indirizzo).
Tim Čas

3

Uso questa parola chiave per documentare esplicitamente quando è fondamentale per la funzione, che la variabile sia posizionata sullo stack, per i processori basati su stack. Questa funzione può essere richiesta quando si modifica lo stack prima del ritorno da una funzione (o una routine di servizio di interrupt). In questo caso dichiaro:

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

E poi accedo al di fuori della variabile:

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

Quindi la autoparola chiave aiuta a documentare l'intento.


1
Presumo che questo sia solo un intento di segnalazione, dal momento che la parola chiave in realtà non impone il posizionamento dello stack, più che semplicemente ometterlo.
underscore_d

2

Secondo Stroustrup, in "The C Programming Language" (4a edizione, che copre C 11), l'uso di 'auto' ha le seguenti ragioni principali (sezione 2.2.2) (le parole di Stroustrup sono citate):

1)

La definizione è in un ampio ambito in cui vogliamo rendere il tipo chiaramente visibile ai lettori del nostro codice.

Con 'auto' e il suo inizializzatore necessario possiamo conoscere il tipo di variabile a colpo d'occhio!

2)

Vogliamo essere espliciti sull'intervallo o sulla precisione della variabile (ad esempio, double piuttosto che float)

Secondo me un caso che si adatta qui, è qualcosa del genere:

   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)

Usando "auto" evitiamo la ridondanza e la scrittura di nomi di tipo lunghi.

Immagina un nome di tipo lungo da un iteratore basato su modelli:

(codice dalla sezione 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;
}

Questi punti si applicano a C ++ 11, ma non a C ++ 03. L'inferenza del tipo era una novità in C ++ 11.
Jirka Hanika

1

Nel vecchio compilatore, auto era un modo per dichiarare una variabile locale. Non è possibile dichiarare variabili locali in vecchi compilatori come Turbo C senza la parola chiave auto o qualcosa di simile.


Ho paura che ti sbagli. Non c'è mai stato alcun vincolo di questo tipo, nemmeno nella versione originale di Turbo C chiamata Wizard-C nel 1986, o in nessuno dei suoi contemporanei: MSC, Lattice C, Concurrent-C, High-C, Watcom-C ...
chqrlie

1

Il nuovo significato della parola chiave auto in C ++ 0x è descritto molto bene da Stephan T. Lavavej di Microsoft in una conferenza video liberamente visualizzabile / scaricabile su STL che si trova sul sito di MSDN Channel 9 qui .

La lezione merita di essere vista nella sua interezza, ma la parte sulla parola chiave auto si trova circa al 29 ° minuto (circa).


1

C'è qualche altro significato per "auto" diverso da "variabile locale"?

Non in C ++ 03.

Qualcosa che non viene fatto implicitamente per te ovunque tu voglia usarlo?

Assolutamente niente, in C ++ 03.

Come si comporta una variabile automatica nell'ambito del programma? Che dire di una variabile automatica statica nell'ambito del file?

Parola chiave non consentita al di fuori del corpo di una funzione / metodo.

Questa parola chiave ha uno scopo [in C ++ 03] diverso dal semplice esistere per completezza?

Sorprendentemente, sì. I criteri di progettazione di C ++ includevano un alto grado di compatibilità con le versioni precedenti con C. C aveva questa parola chiave e non c'era motivo reale per vietarla o ridefinirne il significato in C ++. Quindi, lo scopo era un'incompatibilità in meno con C.

Questa parola chiave ha uno scopo in C diverso dal solo esistere per completezza?

Ne ho appreso uno solo di recente: la facilità di porting di vecchi programmi da B. C si è evoluto da un linguaggio chiamato B la cui sintassi era abbastanza simile a quella di C. Tuttavia, B non aveva alcun tipo. L'unico modo per dichiarare una variabile in B era specificarne il tipo di archiviazione ( autoo extern). Come questo:

auto i;

Questa sintassi funziona ancora in C ed è equivalente a

int i;

perché in C, il valore predefinito della classe di archiviazione è autoe il tipo è predefinito int. Immagino che ogni singolo programma che ha avuto origine in B ed è stato portato in C fosse letteralmente pieno di autovariabili in quel momento.

C ++ 03 non consente più lo stile C implicit int, ma ha conservato la autoparola chiave non più esattamente utile perché, a differenza dell'int implicito, non era noto per causare problemi nella sintassi di C.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.