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 da p 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 };
    /*...*/
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow