"Inserire una variabile nello stack" è un termine improprio in C ++?

0

In C ++ una variabile è allocata in "Call Stack" ("Stack") o "Heap". Frequentemente quando ci si riferisce all'assegnazione di una variabile allo "Stack", le persone usano la frase "Push to the stack".

Il mio problema con questo è che le variabili allocate allo Stack possono essere accedute in modo casuale in qualsiasi ordine. Pertanto, le variabili non vengono memorizzate in una pila e la parola "Push" dovrebbe essere evitata per evitare ambiguità al suo significato. (I.e "Push" come nella funzione stack comune, o "Push" come in altri significati)

Piuttosto, lo "Stack" è uno stack rispetto a "Stack Frames" NON le variabili locali all'interno di "Stack Frame".

Ho ragione nel ritenere che la frase corretta dovrebbe essere "Assegna allo Stack?"

    
posta M. Evers 03.10.2016 - 20:10
fonte

4 risposte

7

Una pila è una struttura di dati in cui è possibile solo aggiungere alla fine e rimuovere solo alla fine, senza la possibilità di manipolare nessun altro elemento. Non significa necessariamente che puoi leggere l'ultimo elemento nello stack. (Molte implementazioni specifiche permetteranno infatti di leggere solo l'ultimo elemento, ma altre consentiranno a qualsiasi elemento dello stack di essere pronto, esponendo eventualmente l'accesso casuale per posizione.)

Per quanto riguarda lo stack di chiamate, puoi sempre solo allocare nuovi elementi alla fine dello stack e rilasciare sempre e solo dalla stessa estremità dello stack, quindi queste operazioni sono di fatto semanticamente identico alle operazioni generali "push" e "pop". Il fatto che i vari elementi nello stack possano essere letti attraverso l'accesso casuale non cambia nulla.

Mentre sarà il caso che, come dettaglio di implementazione, più elementi verranno spinti e prelevati dallo stack tutto in una volta come un'ottimizzazione, non cambia il fatto che concettualmente , tu stai ancora spingendo e saltando da una pila logica. Il fatto che uno stack frame spinga più oggetti quando inserito, e facendo scoppiare più oggetti quando si esce, è ancora coerente con quello. Naturalmente se pensi allo stack come a spingere e scoppiare intere cornici dello stack che soddisfa anche tutti i criteri di uno stack logico, se preferisci pensarlo in questo modo, ma non hai pensarlo in questo modo.

    
risposta data 03.10.2016 - 20:44
fonte
1

C e C ++ (prima di C ++ 11) usano la parola chiave opzionale auto per le variabili locali. auto significa automatico, ovvero queste variabili vengono create automaticamente entrando nello scope in cui sono dichiarate e automaticamente eliminate uscendo da tale ambito.

(Con C ++ 11 la parola chiave auto ha ricevuto nuovi significati.)

Am I correct in thinking that the correct phrase should be "Allocate to the Stack?"

Poiché le variabili locali sono automaticamente allocate, costruite, destrutturate e liberate, preferirei chiamarle semplicemente "variabili locali" (in comune volgare) o variabili automatiche (nella vecchia terminologia di linguaggio C / C ++), ma se dovessi , Direi "allocato nello stack".

Quando qualcuno parla di "push (on) to the stack", almeno per me, evoca la nozione di passare parametri, poiché con (parti di) molte convenzioni di chiamata, il passaggio di un argomento reale può essere fatto da operazione push, specialmente quando i parametri superano i registri degli argomenti. Tale spinta è spesso ordinata come lo sono gli argomenti / i parametri formali effettivi.

Sebbene un problema riguardi tutto questo, un buon compilatore preferirà i registri sulla memoria quando possibile. Un compilatore è anche libero di usare a volte un registro e altre volte usa la memoria per la stessa variabile, a patto che sia in grado di tenerlo tutto dritto (cioè non fa alcun tipo di errore nel farlo). Può riutilizzare la stessa memoria o lo stesso / i registro / i per diverse variabili locali se può determinare che la loro durata non si sovrapponga.

Quindi, a volte le variabili locali non ottengono alcuno spazio di stack allocato perché è allocato ai registri o riusando una memoria esistente.

Dico che la migliore terminologia è chiamarle solo variabili locali o descriverle come dichiarate localmente.

    
risposta data 03.10.2016 - 20:55
fonte
1

Le variabili automatiche in C non vengono inserite, allocate o simili; la frase migliore che riesco a pensare per descrivere il processo è "resa spazio per". Il fatto che lo stack sia coinvolto è un dettaglio di implementazione che, sebbene popolare, non è obbligatorio per la lingua.

Il compilatore sa quanto spazio occuperà le variabili automatiche in un blocco perché devono essere dichiarate. All'ingresso, il compilatore invierà * il contenuto di tutti i registri che intende sovrascrivere e quindi spinge il puntatore dello stack di abbastanza byte per contenere gli automatismi. ** Lo spazio lasciato nello stack viene trattato come struct , con ogni automatico avere un offset noto rispetto al puntatore dello stack, che sarà sempre nella stessa posizione quando quel blocco è in esecuzione.

I puristi faranno correttamente notare che questo comportamento è un abuso dello stack come una struttura di dati. Quando stai scrivendo assemblea, non c'è proprio nulla di simile. Il puntatore dello stack è solo un posto in cui tenere un indirizzo e nulla impedisce al codice in esecuzione di guardare in qualsiasi punto dello stack. Sembra pericoloso, ma è per questo che cerchiamo di lasciare che le persone intelligenti scrivano compilatori: sono abbastanza disciplinati da usare la motosega per fare cose buone senza rimuovere un arto che avrebbe dovuto rimanere.

* Il codice compilato potrebbe non utilizzare effettivamente l'istruzione PUSH del processore per farlo. Può regolare il puntatore dello stack e fare depositi relativi ad esso; che è lo stesso metodo descritto qui per gli automatismi.

** Questo è soggetto a ottimizzazioni; non tutti gli automatismi hanno bisogno di memoria reale e possono essere tenuti in un registro se il compilatore lo ritiene opportuno.

    
risposta data 03.10.2016 - 21:42
fonte
1

È una metafora che funziona bene come modello per chiamare subroutine, passare argomenti e ritornare al punto della chiamata. Il concetto di pila in questo contesto non rappresenta tanto le qualità fisiche dell'implementazione, ma la sequenza logica degli eventi. Illustra che tenere traccia di un singolo puntatore dello stack consente di nidificare le chiamate di subroutine in modo facilmente controllato.

Se si guarda abbastanza vicino a un'implementazione, qualsiasi astrazione si romperà. Ti farà anche allontanare dall'essenza della questione. La metafora dello stack ha senso finché ti concentri sull'esecuzione del programma. Se ti concentri invece sulla memorizzazione dei dati, potresti vedere un'astrazione diversa come quella geografica che parla delle variabili locali e globali.

    
risposta data 03.10.2016 - 21:58
fonte

Leggi altre domande sui tag