in che modo array [100] = {0} imposta l'intero array su 0?


140

In che modo il compilatore inserisce i valori char array[100] = {0};? Qual è la magia dietro?

Volevo sapere come inizializza internamente il compilatore.


1
In C o C ++? Sono due domande separate.
Toby Speight,

Risposte:


163

Non è magia.

Il comportamento di questo codice in C è descritto nella sezione 6.7.8.21 della specifica C ( bozza online della specifica C ): per gli elementi che non hanno un valore specificato, il compilatore inizializza i puntatori su NULL e i tipi aritmetici su zero ( e ricorsivamente si applica agli aggregati).

Il comportamento di questo codice in C ++ è descritto nella sezione 8.5.1.7 della specifica C ++ ( bozza online della specifica C ++ ): il compilatore aggrega inizializza gli elementi che non hanno un valore specificato.

Inoltre, tieni presente che in C ++ (ma non in C), puoi utilizzare un elenco di inizializzatori vuoto, facendo in modo che il compilatore inizializzi in modo aggregato tutti gli elementi dell'array:

char array[100] = {};

Per quanto riguarda il tipo di codice che il compilatore potrebbe generare quando lo fai, dai un'occhiata a questa domanda: Strano assembly dall'inizializzazione dell'array 0


Tutti i compilatori C fanno questo? Sono stato portato a credere che solo Visual Studio lo faccia.
JFA,

1
bozza online di specifiche c ++ non funzionante, qualcuno ha un nuovo link?
Behrooz Karjoo,

35

L'implementazione dipende dagli sviluppatori del compilatore.

Se la tua domanda è "cosa accadrà con tale dichiarazione", il compilatore imposterà il primo elemento dell'array sul valore che hai fornito (0) e tutti gli altri verranno impostati su zero perché è un valore predefinito per gli elementi dell'array omessi.


Non ho una fonte, ma sono abbastanza sicuro di aver letto da qualche parte che non esiste un valore predefinito per le dichiarazioni di array; ottieni qualunque spazzatura fosse già lì. Non ha senso perdere tempo a impostare questi valori quando è probabile che li sovrascrivi comunque.
Ryan Fox,

10
Ryan, se non imposti un valore per il primo elemento in cui l'intero array non è inizializzato e contiene effettivamente immondizia, ma se imposti un valore per almeno un elemento di esso l'intero array viene inizializzato in modo che gli elementi non specificati vengano inizializzati implicitamente a 0.
qrdl

1
Per C ++ un elenco di inizializzatori vuoto per un array limitato limita-inizializza tutti gli elementi.
dalle

2
@NatanYellin Dove ho detto che questo non è definito? Si prega di leggere la risposta completa prima di commentare e ridimensionare.
qrdl

1
@qrdl Hai ragione. Ho frainteso il tuo commento sull'implementazione. Purtroppo, non posso cambiare il mio voto ora.
Natan Yellin

27

Se il tuo compilatore è GCC, puoi anche utilizzare la sintassi seguente:

int array[256] = {[0 ... 255] = 0};

Si prega di consultare http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits e notare che questa è una funzione specifica del compilatore .


Benvenuto! da quando hai chiesto Cerca più simili tipi di trucchi, io avevo fornito
lakshmanaraj

1
Puoi sicuramente farlo se lo desideri, ma ci sono ovvi svantaggi nel fare affidamento su estensioni specifiche del compilatore come questa.
Dan Olson

@Dan Olson la sua stessa domanda si sta ponendo riguardo al compilatore specifico e quindi ha pubblicato questo. Se ritieni che sia inutile, lo eliminerò.
Lakshmanaraj,

5
Non è inutile, è interessante. L'avvertimento merita solo di essere notato.
Dan Olson

2
È roba del genere che mi fa tornare su SO e leggere più delle prime poche risposte ...
tim

19

Dipende da dove metti questa inizializzazione.

Se l'array è statico come in

char array[100] = {0};

int main(void)
{
...
}

quindi è il compilatore che riserva i 100 0 byte nel segmento di dati del programma. In questo caso avresti potuto omettere l'inizializzatore.

Se il tuo array è automatico, allora è un'altra storia.

int foo(void)
{
char array[100] = {0};
...
}

In questo caso ad ogni chiamata della funzione foo avrai un memset nascosto.

Il codice sopra è equivalente a

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

e se si omette l'inizializzatore, l'array conterrà dati casuali (i dati dello stack).

Se l'array locale è dichiarato statico come in

int foo(void)
{ 
static char array[100] = {0};
...
}

quindi è tecnicamente lo stesso caso del primo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.