¿Cómo la matriz [100] = {0} establece la matriz completa en 0?

140

¿Cómo rellena los valores el compilador char array[100] = {0};? ¿Cuál es la magia detrás de esto?

Quería saber cómo se inicializa internamente el compilador.

Namratha Patil
fuente
1
En C o C ++? Son dos preguntas separadas.
Toby Speight

Respuestas:

163

No es magia

El comportamiento de este código en C se describe en la sección 6.7.8.21 de la especificación C ( borrador en línea de la especificación C ): para los elementos que no tienen un valor especificado, el compilador inicializa los punteros a NULL y los tipos aritméticos a cero ( y aplica esto recursivamente a los agregados).

El comportamiento de este código en C ++ se describe en la sección 8.5.1.7 de la especificación C ++ ( borrador en línea de la especificación C ++ ): el compilador agrega-inicializa los elementos que no tienen un valor especificado.

Además, tenga en cuenta que en C ++ (pero no en C), puede usar una lista de inicializadores vacía, haciendo que el compilador agregue-inicialice todos los elementos de la matriz:

char array[100] = {};

En cuanto a qué tipo de código puede generar el compilador cuando hace esto, eche un vistazo a esta pregunta: ensamblaje extraño desde la inicialización de la matriz 0

bk1e
fuente
¿Todos los compiladores de C hacen esto? Se me hizo creer que solo Visual Studio hace esto.
JFA
1
borrador en línea de especificaciones de c ++ roto, ¿alguien tiene un nuevo enlace?
Behrooz Karjoo
35

La implementación depende de los desarrolladores del compilador.

Si su pregunta es "qué sucederá con dicha declaración", el compilador establecerá el primer elemento de la matriz en el valor que ha proporcionado (0) y todos los demás se establecerán en cero porque es un valor predeterminado para los elementos de la matriz omitidos.

qrdl
fuente
No tengo una fuente, pero estoy bastante seguro de que leí en alguna parte que no hay un valor predeterminado para las declaraciones de matriz; obtienes la basura que ya estaba allí. No tiene sentido perder el tiempo configurando estos valores cuando es probable que los sobrescriba de todos modos.
Ryan Fox
10
Ryan, si no configuras un valor para el primer elemento en el que toda la matriz no está inicializada y, de hecho, contiene basura, pero si configuras un valor para al menos un elemento, la matriz completa se inicializa para que los elementos no especificados se inicialicen implícitamente en 0.
qrdl
1
Para C ++, una lista de inicializadores vacía para una matriz limitada inicializa por defecto todos los elementos.
dalle
2
@NatanYellin ¿Dónde dije que esto no está definido? Lea la respuesta completa antes de comentar y votar a favor.
qrdl
1
@qrdl Tienes razón. No entendí tu comentario sobre la implementación. Lamentablemente, no puedo cambiar mi voto ahora.
Natan Yellin
27

Si su compilador es GCC, también puede usar la siguiente sintaxis:

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

Consulte http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits , y tenga en cuenta que esta es una característica específica del compilador .

lakshmanaraj
fuente
¡Bienvenidos! ya que preguntas por mirar más de tales tipo de trucos, que había proporcionado
lakshmanaraj
1
Ciertamente puede hacer esto si lo desea, pero existen desventajas obvias al confiar en extensiones específicas del compilador como esta.
Dan Olson
@Dan Olson, su propia pregunta es sobre el compilador específico y, por lo tanto, publicó esto. Si crees que es inútil, lo eliminaré.
lakshmanaraj
55
No es inútil, es interesante. La advertencia merece ser notada.
Dan Olson
2
Cosas que de esta manera que me hace volver a SO y leer más de los mejores pocas respuestas ...
timday
19

Depende de dónde coloque esta inicialización.

Si la matriz es estática como en

char array[100] = {0};

int main(void)
{
...
}

entonces es el compilador que reserva los 100 0 bytes en la división de datos del programa. En este caso, podría haber omitido el inicializador.

Si su matriz es automática, entonces es otra historia.

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

En este caso, en cada llamada de la función foo tendrá un memset oculto.

El código anterior es equivalente a

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

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

y si omite el inicializador, su matriz contendrá datos aleatorios (los datos de la pila).

Si su matriz local se declara estática como en

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

entonces es técnicamente el mismo caso que el primero.

LPs
fuente