Dove viene utilizzata la parola chiave C auto?


104

Ai tempi del college ho letto di auto parola chiave e nel corso del tempo ho effettivamente dimenticato di cosa si tratta. È definito come:

definisce una variabile locale come avente una durata locale

Non ho mai trovato che venga usato da nessuna parte, è davvero usato e se sì allora dove viene usato e in quali casi?

Risposte:


90

autoè un modificatore come static. Definisce la classe di archiviazione di una variabile. Tuttavia, poiché l'impostazione predefinita per le variabili locali è auto, normalmente non è necessario specificarla manualmente.

Questa pagina elenca diverse classi di archiviazione in C.


13
Stavo solo guardando di nuovo dopo che qualcuno ha votato la mia risposta. Dici che "normalmente non è necessario specificarlo manualmente". Non mi resta che chiedere: esiste effettivamente una circostanza in cui auto può essere specificato ma non avverrà di default?
Jerry Coffin,

2
@ JerryCoffin Non in C. In C ++ 11, è riproposto e puoi usarlo per ottenere efficacemente l'inferenza del tipo di variabile locale.
Mehrdad Afshari

2
Un possibile utilizzo è nella dichiarazione anticipata di funzioni annidate in GNU C, sebbene questo sia un dirottamento della definizione originale di auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah

2
La pagina collegata è obsoleta. Dal C11, c'è anche _Thread_localdettagli: en.cppreference.com/w/c/language/storage_duration e stackoverflow.com/a/14289720/6557621
MCCCS

132

Se leggessi l' elenco IAQ (Domande poco frequenti), sapresti che l'auto è utile principalmente per definire o dichiarare un veicolo:

auto my_car;

Un veicolo parcheggiato costantemente all'aperto:

extern auto my_car;

Per coloro che non hanno senso dell'umorismo e vogliono "solo i fatti, signora": la risposta breve è che non c'è mai alcun motivo per usarli auto. L'unica volta che puoi usare autoè con una variabile che ha già una autoclasse di archiviazione, quindi stai solo specificando qualcosa che accadrebbe comunque. Il tentativo di utilizzare autosu qualsiasi variabile che non dispone autogià della classe di archiviazione comporterà il rifiuto del codice da parte del compilatore. Suppongo che se vuoi ottenere informazioni tecniche, la tua implementazione non deve essere un compilatore (ma lo è) e può teoricamente continuare a compilare il codice dopo aver emesso una diagnostica (ma non lo farà).

Piccola aggiunta di kaz :

C'è anche:

static auto my_car;

che richiede una diagnosi secondo ISO C.E 'corretto, perché dichiara che l'auto è in panne. La diagnostica è gratuita, ma spegnere la luce del cruscotto ti costerà ottanta dollari. (Venti o meno, se acquisti il ​​tuo dongle USB per la diagnostica di bordo da eBay).

Il suddetto extern auto my_carrichiede anche una diagnostica e per questo motivo non viene mai eseguito dal compilatore, se non dal personale comunale incaricato del controllo del parcheggio.

Se vedi molto extern static auto ...in qualsiasi codice di base, sei in un brutto quartiere; cerca subito un lavoro migliore, prima che l'intero posto si trasformi in Rust.


@self .: L'ISO sembra non sapere di una "ISO 2011". Cosa credi che potrebbe standardizzare?
Jerry Coffin

6
Meno male che non avevo in bocca caffè, cola, birra scura o qualche altro liquido di colore scuro. Mi dovreste uno schermo di computer, @JerryCoffin, se fosse così. LA MIGLIORE RISPOSTA MAI!
David Hammen

2
@ Dan: Onestamente ti ci è voluto "un bel po '" per leggere 5 righe di testo e arrivare alla parte in cui dice: "la risposta breve è che non c'è mai alcun motivo per usare l'auto"? Sul serio? Visto il commento immediatamente precedente al tuo, sembra che almeno alcune persone lo trovino un contributo positivo.
Jerry Coffin

@ JerryCoffin l'ho già spiegato, leggi di nuovo il mio commento. Il senno di poi è 20/20.
Dan Bechard

2
Di recente ho superato una grave conflagrazione (chiuso due corsie) che suggerisce la necessità dichar auto my_car;
forte

46

La autoparola chiave è inutile nel linguaggio C. È lì perché prima del linguaggio C esisteva un linguaggio B in cui quella parola chiave era necessaria per dichiarare le variabili locali. (B è stato sviluppato in NB, che è diventato C).

Ecco il manuale di riferimento per B .

Come puoi vedere, il manuale è pieno di esempi in cui autoviene utilizzato. Questo è così perché non ci sono intparole chiave. È necessario un qualche tipo di parola chiave per dire "questa è una dichiarazione di una variabile", e quella parola chiave indica anche se è locale o esterna ( autocontro extrn). Se non usi l'uno o l'altro, hai un errore di sintassi. Vale a dire, x, y;non è una dichiarazione di per sé, ma lo auto x, y;è.

Poiché le basi di codice scritte in B dovevano essere portate su NB e su C man mano che il linguaggio veniva sviluppato, le versioni più recenti del linguaggio portavano un po 'di bagaglio per una migliore compatibilità all'indietro che si traduceva in meno lavoro. Nel caso di auto, i programmatori non dovevano scovare ogni occorrenza diauto e rimuoverlo.

È ovvio dal manuale che l'ormai obsoleto "int implicito" cruft in C (essere in grado di scrivere main() { ... }senza nulla intdavanti) proviene anche da B. Questa è un'altra caratteristica di compatibilità all'indietro per supportare il codice B. Le funzioni non hanno un tipo restituito specificato in B perché non esistono tipi. Tutto è una parola, come in molti linguaggi assembly.

Nota come una funzione può solo essere dichiarata extrn putchare quindi l'unica cosa che lo rende una funzione che di identificatore l'uso : è usato in un'espressione di una funzione chiamata del genere putchar(x), ed è quello che dice al compilatore di trattare quella parola senza tipo come un puntatore a funzione.


24

In C autoè una parola chiave che indica che una variabile è locale in un blocco. Poiché è l'impostazione predefinita per le variabili con ambito di blocco, non è necessario e viene utilizzato molto raramente (non credo di averlo mai visto usare al di fuori degli esempi nei testi che discutono la parola chiave). Sarei interessato se qualcuno potesse indicare un caso in cui l'uso diauto stato richiesto per ottenere un'analisi o un comportamento corretto.

Tuttavia, nello standard C ++ 11 la autoparola chiave è stata "dirottata" per supportare l'inferenza del tipo, dove il tipo di una variabile può essere preso dal tipo del suo inizializzatore:

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

L'inferenza del tipo viene aggiunta principalmente per supportare la dichiarazione delle variabili nei modelli o restituiti dalle funzioni del modello in cui i tipi basati su un parametro del modello (o dedotti dal compilatore quando viene istanziato un modello) possono spesso essere piuttosto dolorosi da dichiarare manualmente.


1
"La variabile è locale in un blocco" - non è affatto vero. Tutte le variabili dichiarate in un blocco sono locali a quel blocco (rispetto all'ambito). Potrebbero essere collegati ad altre variabili nel programma, ma la dichiarazione è visibile solo in quel blocco. autoriguarda la classe di archiviazione che non ha nulla a che fare con la visibilità.
fuz

12

Con il vecchio compilatore Aztec C, era possibile trasformare tutte le variabili automatiche in variabili statiche (per una maggiore velocità di indirizzamento) utilizzando un'opzione della riga di comando.

Ma le variabili dichiarate esplicitamente con autosono state lasciate così come sono in quel caso. (Un must per le funzioni ricorsive che altrimenti non funzionerebbero correttamente!)


7

La autoparola chiave è simile all'inclusione del punto e virgola in Python, era richiesta da un linguaggio precedente ( B) ma gli sviluppatori si sono resi conto che era ridondante perché la maggior parte delle cose lo erano auto.

Sospetto che sia stato lasciato per aiutare con il passaggio da B a C. In breve, un uso è per la compatibilità del linguaggio B.

Ad esempio in B e 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');
}

1

La parola chiave Auto è un esempio di classe di archiviazione (una sorta di tecnica che decide la durata della variabile e il luogo di archiviazione). Ha un comportamento in base al quale la variabile creata dall'Help di quella parola chiave ha durata (durata) risiede solo all'interno delle parentesi graffe

{
    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
}          

0

autopuò essere utilizzato solo per variabili con ambito di blocco. extern auto intè spazzatura perché il compilatore non può determinare se questo utilizza una definizione esterna o se sovrascrivere l'extern con una definizione automatica (anche auto ed extern sono durate di archiviazione completamente diverse, come static auto int, che è anche spazzatura ovviamente). Potrebbe sempre scegliere di interpretarlo in un modo, ma invece sceglie di trattarlo come un errore.

C'è una funzionalità che autofornisce e che abilita la regola "tutto è un int" all'interno di una funzione. A differenza dell'esterno di una funzione, dove a=3viene interpretato come una definizione int a =3perché gli assegnamenti non esistono nell'ambito del file, a=3è un errore all'interno di una funzione perché apparentemente il compilatore lo interpreta sempre come un assegnamento a una variabile esterna piuttosto che come una definizione (anche se esiste sono extern int adichiarazioni previsionali in funzione o in ambito di file), ma una specifica come static, const, volatileo autoavrebbe implica che si tratta di una definizione e il compilatore lo prende come una definizione, ad eccezione di autonon avere gli effetti collaterali degli altri committenti. auto a=3è quindi implicitamente ha lo stesso effetto eauto int a = 3 . Certo,signed a = 3unsigned a = 3 è sempre un int senza segno.

Nota anche " autonon ha effetto sul fatto che un oggetto verrà assegnato a un registro (a meno che qualche particolare compilatore non presti attenzione ad esso, ma ciò sembra improbabile)"


-1

Sono sicuro che tu abbia familiarità con gli specificatori della classe di archiviazione in C che sono "extern", "static", "register" e "auto". La definizione di "auto" è più o meno data in altre risposte, ma qui c'è un possibile utilizzo della parola chiave "auto" di cui non sono sicuro, ma penso che dipenda dal compilatore. Vedi, per quanto riguarda gli specificatori della classe di archiviazione, c'è una regola. Non è possibile utilizzare più specificatori di classe di archiviazione per una variabile. Ecco perché le variabili globali statiche non possono essere esternate. Pertanto, sono noti solo al loro file. Quando vai alle impostazioni del compilatore, puoi abilitare il flag di ottimizzazione per la velocità. uno dei modi in cui il compilatore ottimizza è, cerca le variabili senza specificatori di classe di archiviazione e quindi effettua una valutazione basata sulla disponibilità della memoria cache e alcuni altri fattori per vedere se deve trattare quella variabile utilizzando o meno l'identificatore di registro. Ora, cosa succede se vogliamo ottimizzare il nostro codice per la velocità sapendo che una variabile specifica nel nostro programma non è molto importante e non vogliamo che il compilatore la consideri nemmeno come registro. Tuttavia, inserendo auto, il compilatore non sarà in grado di aggiungere un identificatore di registro a una variabile poiché digita "register auto int a;" OPPURE "auto register int a;" solleva l'errore di utilizzare più specificatori di classe di archiviazione. Per riassumere, ho pensato che auto potesse proibire al compilatore di trattare una variabile come registro tramite l'ottimizzazione. cosa succede se vogliamo ottimizzare il nostro codice per la velocità sapendo che una variabile specifica nel nostro programma non è molto importante e non vogliamo che il compilatore la consideri nemmeno come registro. Tuttavia, inserendo auto, il compilatore non sarà in grado di aggiungere un identificatore di registro a una variabile poiché digita "register auto int a;" OPPURE "auto register int a;" solleva l'errore di utilizzare più specificatori di classe di archiviazione. Per riassumere, ho pensato che auto potesse proibire al compilatore di trattare una variabile come registro tramite l'ottimizzazione. cosa succede se vogliamo ottimizzare il nostro codice per la velocità sapendo che una variabile specifica nel nostro programma non è molto importante e non vogliamo che il compilatore la consideri nemmeno come registro. Tuttavia, inserendo auto, il compilatore non sarà in grado di aggiungere un identificatore di registro a una variabile poiché digita "register auto int a;" OPPURE "auto register int a;" solleva l'errore di utilizzare più specificatori di classe di archiviazione. Per riassumere, ho pensato che auto potesse proibire al compilatore di trattare una variabile come registro tramite l'ottimizzazione. solleva l'errore di utilizzare più specificatori di classe di archiviazione. Per riassumere, ho pensato che auto potesse proibire al compilatore di trattare una variabile come registro tramite l'ottimizzazione. solleva l'errore di utilizzare più specificatori di classe di archiviazione. Per riassumere, ho pensato che auto potesse proibire al compilatore di trattare una variabile come registro tramite l'ottimizzazione.

Questa teoria non ha funzionato per il compilatore GCC, tuttavia non ho provato altri compilatori.

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.