Domanda

  

Nota questa domanda è stata originariamente pubblicata nel 2009, prima che il C ++ 11 fosse ratificato e prima che il significato della parola chiave auto fosse drasticamente modificato. Le risposte fornite riguardano solo al significato C ++ 03 di static - che è una classe di memoria specificata - e non il significato C ++ 11 di static auto - che è automatico deduzione del tipo. Se stai cercando consigli su quando usare C ++ 11 <=>, questa domanda non è rilevante per quella domanda.

Per molto tempo ho pensato che non c'era motivo di usare la parola 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 <=> all'interno di un ambito di blocco le avrebbe dato una durata permanente, e dichiararla al di fuori dell'ambito di blocco (nell'ambito del programma) le avrebbe dato un ambito di file (accessibile solo in quell'unità di compilazione ).

Quindi questo mi lascia con una sola parola chiave che (forse) non capisco ancora del tutto: la <=> parola chiave. C'è qualche altro significato diverso da "variabile locale?" Qualcosa che fa che non è implicitamente fatto per te ovunque tu voglia usarlo? Come si comporta una variabile <=> nell'ambito del programma? Che dire di una <=> variabile nell'ambito del file? Questa parola chiave ha uno scopo diverso da esistente per completezza ?

È stato utile?

Soluzione

auto è un identificatore della classe di archiviazione, static, register e extern. Puoi usare solo uno di questi quattro in una dichiarazione.

Le variabili locali (senza i) hanno una durata di memorizzazione automatica, il che significa che vivono dall'inizio della loro definizione fino alla fine del loro blocco. Mettere l'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 renderlo valido sintassi o disambiguare da un'espressione di assegnazione nel caso in cui a rientri nell'ambito. Ma questo non funziona in C ++ (devi specificare un tipo). Abbastanza divertente, lo standard C ++ scrive:

  

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

che si riferisce al seguente scenario, che potrebbe essere un cast da int a <=> o la dichiarazione di una variabile <=> di tipo <=> con parentesi ridondanti intorno a <=>. È sempre considerata una dichiarazione, quindi <=> non aggiungerebbe nulla di utile qui, ma invece per l'umano. Ma ancora una volta, l'essere umano starebbe meglio rimuovendo le parentesi ridondanti intorno a <=>, direi:

int(a);

Con il nuovo significato di <=> che arriva con C ++ 0x, scoraggerei usandolo con il significato di C ++ 03 nel codice.

Altri suggerimenti

In C ++ 11, auto ha un nuovo significato: ti 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 std::list<int>::iterator lì crea un iteratore di tipo <=>.

Questo può rendere molto più semplice la lettura di alcuni codici molto complessi.

Un altro esempio:

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

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

Al momento la parola chiave auto non ha scopo. Hai perfettamente ragione sul fatto che ripristina semplicemente la classe di archiviazione predefinita di una variabile locale, l'alternativa davvero utile è static.

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

GCC ha un uso speciale di auto per le funzioni nidificate - vedi qui .

Se si dispone di una funzione nidificata che si desidera chiamare prima della sua definizione, è necessario dichiararla con <=>.

&

quot; auto quot &; presumibilmente dice al compilatore di decidere autonomamente dove inserire la variabile (memoria o registro). Il suo analogo è & Quot; register & Quot ;, che presumibilmente dice al compilatore di provare a tenerlo in un registro. I compilatori moderni ignorano entrambi, quindi dovresti farlo anche tu.

Uso questa parola chiave per documentare esplicitamente quando è fondamentale per la funzione, che la variabile sia posizionata nello stack, per i processori basati su stack. Questa funzione può essere richiesta quando si modifica lo stack prima di tornare da una funzione (o interrompere la routine di servizio). 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 auto parola chiave aiuta a documentare l'intento.

Secondo Stroustrup, in " Il linguaggio di programmazione C " (4a edizione, che copre C 11), l'uso di "auto" ha i seguenti motivi principali (sezione 2.2.2) (sono citate le parole di Stroustrup):

1)

  

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

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

2)

  

Vogliamo essere espliciti sull'intervallo o sulla precisione della variabile (ad es. double anziché 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 ridondanza e scriviamo nomi di tipo lunghi.

Immagina un nome di tipo lungo da un iteratore templatized:

(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;
}

Nel vecchio compilatore, auto era un modo per dichiarare una variabile locale. Non è possibile dichiarare variabili locali nei compilatori precedenti come Turbo C senza la parola chiave auto o alcuni di questi.

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

Vale la pena visualizzare la lezione nella sua interezza, ma la parte relativa alla parola chiave auto si trova all'incirca al 29 ° minuto (circa).

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

Non in C ++ 03.

Tutto ciò che fa che non è implicitamente fatto per te ovunque tu voglia usarlo?

Nulla di tutto, in C ++ 03.

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

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

Questa parola chiave ha uno scopo [in C ++ 03] diverso da quello esistente per completezza?

Sorprendentemente sì. I criteri di progettazione C ++ includevano un alto grado di compatibilità con le versioni precedenti di C. C aveva questa parola chiave e non vi era alcuna ragione 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 da quello esistente per completezza?

Ne ho imparato uno solo di recente: la facilità di porting di programmi antichi da B. C si è evoluta 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 specificare il suo tipo di archiviazione (auto o extern). In questo modo:

  

auto i;

Questa sintassi funziona ancora in C ed è equivalente a

  

int i;

perché in C, la classe di archiviazione predefinita è int e il tipo predefinito è <=>. Immagino che ogni singolo programma che ha avuto origine in B ed è stato portato su C era letteralmente pieno di <=> variabili in quel momento.

C ++ 03 non consente più l'int implicito di stile C, ma ha conservato la parola chiave <=> non più esattamente utile poiché, diversamente dall'int implicito, non era noto che causasse problemi nella sintassi di C.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top