I valori letterali delle stringhe sono array - oggetti di dimensioni intrinsecamente imprevedibili (cioè di dimensioni definite dall'utente e possibilmente di grandi dimensioni). In generale, non c'è altro modo di rappresentare tali letterali se non come oggetti in memoria, cioè come lvalue.Nel C99 ciò vale anche per i valori letterali composti, che sono anche valori l.
Qualsiasi tentativo di nascondere artificialmente il fatto che i valori letterali delle stringhe sono lvalue a livello di linguaggio produrrebbe un numero considerevole di difficoltà completamente inutili, poiché la possibilità di puntare a una stringa letterale con un puntatore e alla possibilità di accedervi poiché un array si basa in modo critico sul fatto che la sua lvalore è visibile a livello di linguaggio.
Nel frattempo, i valori letterali dei tipi scalari hanno dimensioni fisse in fase di compilazione. Allo stesso tempo, è molto probabile che tali valori letterali siano incorporati direttamente nei comandi della macchina sulla specifica architettura hardware. Ad esempio, quando si scrive qualcosa come i = i * 5 + 2
, i valori letterali 5
e 2
diventano parti esplicite (o anche implicite) del codice macchina generato. Non esistono e non hanno bisogno di esistere come posizioni autonome nell'archiviazione dei dati. Non è necessario archiviare i valori 5
e 2
nella memoria di dati.
E 'anche da notare che in molti (se non la maggior parte, o tutti) architetture hardware letterali in virgola mobile sono in realtà implementate come lvalue "nascosti" (anche se la lingua non li espone come tali). Su piattaforme come i comandi macchina x86 di un gruppo in virgola mobile non supportano operandi immediati incorporati. Ciò significa che virtualmente ogni letterale a virgola mobile deve essere memorizzato dal compilatore (e letto dalla memoria dati). Per esempio. quando si scrive qualcosa di simile i = i * 5.5 + 2.1
si traduce in qualcosa di simile
const double unnamed_double_5_5 = 5.5;
const double unnamed_double_2_1 = 2.1;
i = i * unnamed_double_5_5 + unnamed_double_2_1;
In altre parole, letterali in virgola mobile, spesso finiscono per diventare lvalue "non ufficiali" internamente. Tuttavia, è perfettamente logico che le specifiche del linguaggio non abbiano tentato di esporre questo dettaglio di implementazione. A livello linguistico, i letterali aritmetici hanno più senso come valori rituali.
I valori non sono oggetti. Gli Lvalue sono valori che possono apparire sul lato sinistro di un compito, come variabili, membri di strutture e ricerche di elementi dell'array. (L = Left.) – duskwuff
@duskwuff: Il Comitato chiede di dissentire. Per 6.3.2.1, "Un lvalue è un'espressione con un tipo di oggetto o un tipo incompleto diverso da void, se un lvalue non designa un oggetto quando viene valutato, il comportamento non è definito." Per la nota a piè di pagina (53) citata in quella citazione, un lvalue dovrebbe essere considerato come un "valore di localizzatore di oggetti". –
@JohnCalsbeek C++ 11 'risolto', ad es. 'alias {}' è ora possibile. 'U {} .arr' è anche un valore per il tipo di matrice se' arr' è dichiarato come tale nella definizione di classe per 'U'. –