2015-12-11 13 views
5

Cercando di imparare lvalues, rvalues e allocazione di memoria per loro. Quindi con un sacco di materiale didattico c'è un po 'di caos.Come rvalore in C++ memorizzato in memoria?

Un rvalue è un valore che deve esistere solo nei limiti di un'espressione in cui è stato creato (fino almeno a C++ 11). Quindi ha un indirizzo e un blocco di memoria che occupa. Ma per definizione non possiamo ottenere un indirizzo di rvalue, perché si tratta di un oggetto temporaneo in contrasto con uno lvalue. Ma anche prima del C++ 11 siamo riusciti a ottenere un indirizzo di rvalue restituendolo da una funzione e salvandolo in un tipo di riferimento const (uh, suppongo non un indirizzo ma un valore).

Quindi, più precisamente, come funziona l'allocazione rvalue? Per quanto tempo il programma o il sistema operativo ricordano realmente quel luogo di memoria in cui lo rvalue è stato creato e contrassegnato come assegnato e un altro oggetto non può sostituirlo?

Come vedo, ora rvalues vengono memorizzati come ma abbiamo semplicemente altri diritti per accedervi. E hanno altri tipi di deallocation - per lvalues che escono dall'ambito, per rvalues può essere ottimizzato da un'esistenza in limiti di espressione o finché non ci sono più collegamenti ad esso.

+4

lvalue e rvalue sono categorie di espressioni. Non usano alcuna memoria. Quello che usa lo spazio di archiviazione è * oggetti *. (e talvolta, riferimenti). Sembra che tu stia scrivendo "rvalue" quando in realtà intendi "oggetto temporaneo". –

+0

Non penso che i rvalue debbano avere un indirizzo. Possono essere semplicemente valutati in registri. –

+0

@ M.M, hai ragione. –

risposta

5

Risposta breve: dipende dall'implementazione.

Il motivo principale alla base di questo è come sempre la libertà per il compilatore di migliorare le prestazioni del codice. Un modo più concreto per capirlo è ricordare che un valore può essere memorizzato in un registro della CPU e non essere mai effettivamente nella memoria, il che significa più o meno che il valore non ha un indirizzo. Non scommetto tutto ciò che ho su di esso, ma questo è probabilmente uno dei motivi principali per cui "non possiamo ottenere un indirizzo di un valore".

In un modo più generale dal momento che un valore massimo è semanticamente temporaneo è più probabile che venga inserito in luoghi temporanei o ottimizzato in modo tale che non possa essere facilmente mappato a un indirizzo e anche se ciò potrebbe risultare controproducente in termini di prestazione.

4

Concettualmente, i rvalues ​​vivono sullo "stack". Se arrivi al loro indirizzo, è concettualmente un indirizzo da qualche parte in pila. Se l'indirizzo non viene preso affatto, l'entità potrebbe non venire mai realmente in esistenza fintanto che il compilatore imposta le istruzioni corrette per farlo apparire come se fosse stato creato.

Anche se l'entità è realmente creata dove risiede esattamente dipende da varie cose e può anche finire per non essere in pila affatto: potrebbe essere nel frame dello stack corrente ma potrebbe anche essere un altro stack frame o in qualche destregazione se il valore finale viene copiato/spostato lì e il compilatore esegue copia-elisione. Se il rvalue finisce per essere associato a un const&, può anche risiedere in un luogo diverso da quello che avrebbe se non lo fosse.

La durata del valore è vincolata dalle regole del linguaggio. Il modo in cui viene implementato è praticamente il compilatore e/o l'ABI a cui aderisce.

Problemi correlati