Le 15 juillet 17, P0329R4 a été accepté dans lec ++ 20standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
Cela apporte un support limité pourc99Initialiseurs désignés de. Cette limitation est décrite comme suit par C.1.7 [diff.decl] .4, étant donné:
struct A { int x, y; };
struct B { struct A a; };
Les initialisations désignées suivantes, valides en C, sont limitées en C ++:
struct A a = { .y = 1, .x = 2 }
n'est pas valide en C ++ car les désignateurs doivent apparaître dans l'ordre de déclaration des données membres
int arr[3] = { [1] = 5 }
n'est pas valide en C ++ car l'initialisation désignée par tableau n'est pas prise en charge
struct B b = {.a.x = 0}
n'est pas valide en C ++ car les désignateurs ne peuvent pas être imbriqués
struct A c = {.x = 1, 2}
n'est pas valide en C ++ car tous ou aucun des membres de données doivent être initialisés par des désignateurs
Pour c ++ 17et plus tôt Boost prend en charge les initiateurs désignés et il y a eu de nombreuses propositions pour ajouter un support auc ++standard, par exemple: n4172 et la proposition de Daryle Walker pour ajouter une désignation aux initialiseurs . Les propositions citent la mise en œuvre dec99Les initialiseurs désignés de Visual C ++, gcc et Clang revendiquent:
Nous pensons que les changements seront relativement simples à mettre en œuvre
Mais le comité des normes rejette à plusieurs reprises de telles propositions , déclarant:
L'EWG a trouvé divers problèmes avec l'approche proposée et n'a pas pensé qu'il était possible d'essayer de résoudre le problème, car elle a été essayée à plusieurs reprises et chaque fois qu'elle a échoué
Les commentaires de Ben Voigt m'ont aidé à voir les problèmes insurmontables de cette approche; donné:
struct X {
int c;
char a;
float b;
};
Dans quel ordre ces fonctions seraient-elles appelées c99: struct X foo = {.a = (char)f(), .b = g(), .c = h()}
? Étonnamment, dansc99:
L'ordre d'évaluation des sous-expressions dans tout initialiseur est séquencé de manière indéterminée [ 1 ]
(Visual C ++, gcc et Clang semblent avoir un comportement convenu car ils effectueront tous les appels dans cet ordre :)
h()
f()
g()
Mais la nature indéterminée de la norme signifie que si ces fonctions avaient une interaction, l'état du programme résultant serait également indéterminé, et le compilateur ne vous avertirait pas : y a-t-il un moyen d'être averti du mauvais comportement des initialiseurs désignés?
c ++ n'ont des exigences strictes de liste d'initialiseur 11.6.4 [dcl.init.list] 4:
Dans la liste d'initialisation d'une liste d'initialisation accolée, les clauses d'initialisation, y compris celles qui résultent des extensions de pack (17.5.3), sont évaluées dans l'ordre dans lequel elles apparaissent. Autrement dit, chaque calcul de valeur et effet secondaire associé à une clause d'initialisation donnée est séquencé avant chaque calcul de valeur et effet secondaire associé à toute clause d'initialisation qui le suit dans la liste séparée par des virgules de la liste d'initialisation.
Alors c ++ le support aurait exigé que cela soit exécuté dans l'ordre:
f()
g()
h()
Rupture de la compatibilité avec les précédents c99implémentations.
Comme indiqué ci-dessus, ce problème a été contourné par les limitations sur les initialiseurs désignés acceptés dansc ++ 20. Ils fournissent un comportement standardisé, garantissant l'ordre d'exécution des initialiseurs désignés.