Comment le tableau [100] = {0} définit-il le tableau entier sur 0?

140

Comment le compilateur remplit-il les valeurs dans char array[100] = {0}; ? Quelle est la magie derrière ça?

Je voulais savoir comment le compilateur s'initialise en interne.

Namratha Patil
la source
1
En C ou C ++? Ce sont deux questions distinctes.
Toby Speight

Réponses:

163

Ce n'est pas magique.

Le comportement de ce code en C est décrit dans la section 6.7.8.21 de la spécification C ( ébauche en ligne de la spécification C ): pour les éléments qui n'ont pas de valeur spécifiée, le compilateur initialise les pointeurs à NULL et les types arithmétiques à zéro ( et l'applique récursivement aux agrégats).

Le comportement de ce code en C ++ est décrit dans la section 8.5.1.7 de la spécification C ++ ( ébauche en ligne de la spécification C ++ ): le compilateur agrège-initialise les éléments qui n'ont pas de valeur spécifiée.

Notez également qu'en C ++ (mais pas en C), vous pouvez utiliser une liste d'initialisation vide, ce qui oblige le compilateur à agréger-initialiser tous les éléments du tableau:

char array[100] = {};

En ce qui concerne le type de code que le compilateur peut générer lorsque vous faites cela, jetez un œil à cette question: Assemblage étrange du tableau 0-initialisation

bk1e
la source
Est-ce que tous les compilateurs C font cela? J'ai été amené à croire que seul Visual Studio fait cela.
JFA
1
brouillon en ligne des spécifications C ++ cassé, quelqu'un a un nouveau lien?
Behrooz Karjoo
35

La mise en œuvre appartient aux développeurs du compilateur.

Si votre question est "ce qui se passera avec une telle déclaration" - le compilateur définira le premier élément du tableau sur la valeur que vous avez fournie (0) et tous les autres seront mis à zéro car c'est une valeur par défaut pour les éléments du tableau omis.

qrdl
la source
Je n'ai pas de source, mais je suis presque sûr d'avoir lu quelque part qu'il n'y a pas de valeur par défaut pour les déclarations de tableau; vous obtenez les déchets qui s'y trouvaient déjà. Il n'y a aucun sens à perdre du temps à définir ces valeurs lorsque vous risquez de les écraser de toute façon.
Ryan Fox
10
Ryan, si vous ne définissez pas de valeur pour le premier élément, le tableau entier n'est pas initialisé et contient effectivement des déchets, mais si vous définissez une valeur pour au moins un élément de celui-ci, tout le tableau est initialisé afin que les éléments non spécifiés soient initialisés implicitement à 0.
qrdl
1
Pour C ++, une liste d'initialisation vide pour un tableau borné initialise par défaut tous les éléments.
dalle
2
@NatanYellin Où ai-je dit que ce n'était pas défini? Veuillez lire la réponse complète avant de commenter et de voter contre.
qrdl
1
@qrdl Vous avez raison. J'ai mal compris votre commentaire sur la mise en œuvre. Malheureusement, je ne peux pas changer mon vote maintenant.
Natan Yellin
27

Si votre compilateur est GCC, vous pouvez également utiliser la syntaxe suivante:

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

Veuillez consulter http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits , et notez qu'il s'agit d'une fonctionnalité spécifique au compilateur .

lakshmanaraj
la source
Bienvenue! depuis que vous avez demandé de chercher plus de telles sortes d'astuces, j'avais fourni
lakshmanaraj
1
Vous pouvez certainement le faire si vous le souhaitez, mais il y a des inconvénients évidents à compter sur des extensions spécifiques au compilateur comme celle-ci.
Dan Olson
@Dan Olson, sa question lui-même pose des questions sur le compilateur spécifique et a donc publié ceci. Si vous pensez que c'est inutile, je supprimerai.
lakshmanaraj
5
Ce n'est pas inutile, c'est intéressant. La mise en garde mérite juste d'être notée.
Dan Olson
2
Ce sont des trucs comme ça qui me poussent à revenir à SO et à lire plus que les premières réponses ...
jeudi
19

Cela dépend de l'endroit où vous placez cette initialisation.

Si le tableau est statique comme dans

char array[100] = {0};

int main(void)
{
...
}

alors c'est le compilateur qui réserve les 100 0 octets dans le segment de données du programme. Dans ce cas, vous pourriez avoir omis l'initialiseur.

Si votre baie est automatique, c'est une autre histoire.

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

Dans ce cas, à chaque appel de la fonction foo, vous aurez un memset caché.

Le code ci-dessus équivaut à

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

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

et si vous omettez l'initialiseur, votre tableau contiendra des données aléatoires (les données de la pile).

Si votre tableau local est déclaré statique comme dans

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

alors c'est techniquement le même cas que le premier.

LP
la source