29 votes

Une initialisation de tableau (C / C ++) peut-elle se référencer?

Je m'interrogeais sur une initialisation du formulaire suivant:

 int  array[] = {
v - 1,
array[0] + 1
} ;
 

Dans l'initialisation du deuxième élément, la valeur du premier est utilisée, mais le tableau entier n'est pas encore initialisé. Cela arrive à compiler avec g ++, mais je ne savais pas si c'était réellement portable et une construction bien définie?

15voto

phresnel Points 20082

Voir Point 3.3.2 de la déclaration:

Le point de la déclaration d'un nom est immédiatement après sa complète de demande de déclaration (article 8) et avant son initialiseur (le cas échéant), sauf comme il est indiqué ci-dessous. [ Exemple:

int x = 12;
{ int x = x; }

Voici la deuxième x est initialisé avec son propre (indéterminée) de la valeur. fin de l'exemple ]

Si vous vous référez au tableau correctement, son nom est connu après l' =.

Ensuite, 8.5.1 Agrégats:

Un agrégat est un tableau ou une classe [...]

17: Le plein d'expressions dans un initialiseur de la clause sont évaluées dans l'ordre dans lequel ils apparaissent.

Cependant, je ne vois aucune référence à quand évalué, les valeurs sont écrites dans le tableau, je ne voudrais pas compter sur cet et iraient même jusqu'à déclarer votre code n'est pas bien défini.

12voto

Mike Seymour Points 130519

Pour autant que je puisse voir, ce n'est pas bien défini. La norme (C ++ 11, 8.5.1 / 17) spécifie que "les expressions complètes dans une clause d'initialisation sont évaluées dans l'ordre dans lequel elles apparaissent", mais je ne vois rien qui nécessite que chaque élément d'agrégat soit être initialisé à partir du résultat de sa clause d'initialisation avant l'évaluation de la suivante.

1voto

ouah Points 75311

Peut un C/C++) initialisation de tableau de référence lui-même?

Ceci est également valable code C.

C a certaines paragraphe correspondant (l'emphase est mienne).

(C99, 6.2.1p7) "la Structure, de l'union, et l'énumération des balises ont une portée qui commence juste après l'apparition de la balise dans un spécificateur de type qui déclare la balise. Chaque énumération constante a une portée qui commence juste après l'apparition de sa définition de l'énumérateur dans un énumérateur de la liste. Tout autre identifiant de portée qui commence juste après l'achèvement de sa déclaration."

0voto

Je pense que c'est géré par http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343 . Au départ, mon rapport n'était que d'environ non-classe des initialiseurs d'espace de noms pour les objets de portée (voir Quand exactement est un initialiseur temporaire détruit?), mais le problème existe pour l'ensemble des éléments tout aussi bien s'ils sont non-classe. Et l'accroissement de l'récente note explique, semble même exister pour l'ensemble de l'agrégat de l'initialisation de plus, même si c'est un objet de classe, car alors aucun appel du constructeur arrive que serait enlargen la pleine expression de l'initialiseur.

Si, au lieu de int vous avez utilisé une classe, et l'initialisation serait un appel de constructeur, alors que l'appel du constructeur ferait partie de la même expression qui renferme l'ensemble-l'ininitializer élément, de sorte qu'ici, l'ordre serait OK et votre code devrait être bien défini.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X