C Language
Letterali composti
Ricerca…
Sintassi
- (tipo) {inizializzatore-elenco}
Osservazioni
Lo standard C dice in C11-§6.5.2.5 / 3:
Un'espressione postfissa che consiste in un nome di tipo parentesi seguito da un elenco di inizializzatori racchiuso tra parentesi è un letterale composto . Fornisce un oggetto senza nome il cui valore è dato dall'elenco di inizializzazione. 99)
e la nota 99 dice:
Si noti che questo differisce da un'espressione cast. Ad esempio, un cast specifica una conversione in tipi scalari o solo void , e il risultato di un'espressione cast non è un lvalue.
Nota che:
I valori letterali delle stringhe e i letterali composti con tipi qualificati const non devono necessariamente designare oggetti distinti. 101)
101) Ciò consente alle implementazioni di condividere lo spazio di archiviazione per valori letterali costanti e costanti composti costanti con rappresentazioni uguali o sovrapposte.
L'esempio è dato in standard:
C11-§6.5.2.5 / 13:
Come i letterali delle stringhe, i letterali composti const-qualified possono essere inseriti in una memoria di sola lettura e possono anche essere condivisi. Per esempio,
(const char []){"abc"} == "abc"
potrebbe produrre 1 se la memoria dei letterali è condivisa.
Definizione / Inizializzazione di composti letterali
Un letterale composto è un oggetto senza nome che viene creato nell'ambito in cui è definito. Il concetto è stato introdotto per la prima volta nello standard C99. Un esempio per il letterale composto è
Esempi dallo standard C, C11-§6.5.2.5 / 9:
int *p = (int [2]){ 2, 4 };
p
è inizializzato all'indirizzo del primo elemento di una matrice anonima di due interi.
Il composto letterale è un lvalue. La durata di memorizzazione dell'oggetto senza nome è statica (se il letterale viene visualizzato nell'ambito del file) o automatica (se il letterale viene visualizzato nell'ambito del blocco) e in quest'ultimo caso la durata dell'oggetto termina quando il controllo lascia il blocco che lo contiene.
void f(void) { int *p; /*...*/ p = (int [2]){ *p }; /*...*/ }
p
è assegnato l'indirizzo del primo elemento di una matrice di due interi, il primo con il valore precedentemente indicato dap
e il secondo, zero. [...]
Qui p
rimane valido fino alla fine del blocco.
Letterale composto con designatori
(anche da C11)
struct point {
unsigned x;
unsigned y;
};
extern void drawline(struct point, struct point);
// used somewhere like this
drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4});
Un drawline
funzione fittizia riceve due argomenti di tipo struct point
. Il primo ha valori di coordinate x == 1
y == 1
, mentre il secondo ha x == 3
y == 4
Letterale composto senza specificare la lunghezza dell'array
int *p = (int []){ 1, 2, 3};
In questo caso la dimensione dell'array non è specificata, quindi sarà determinata dalla lunghezza dell'inizializzatore.
Letterale composto con lunghezza dell'inizializzatore inferiore alla dimensione dell'array specificata
int *p = (int [10]){1, 2, 3};
il resto degli elementi del letterale composto sarà inizializzato a 0
implicitamente.
Letterale composto di sola lettura
Si noti che un letterale composto è un lvalue e quindi gli elementi possono essere modificabili. È possibile specificare un valore letterale composto di sola lettura utilizzando il qualificatore const
come (const int[]){1,2}
.
Letterale composto contenente espressioni arbitrarie
All'interno di una funzione, un letterale composto, come per ogni inizializzazione da C99, può avere espressioni arbitrarie.
void foo()
{
int *p;
int i = 2; j = 5;
/*...*/
p = (int [2]){ i+j, i*j };
/*...*/
}