Il 15 luglio 17 P0329R4 è stato accettato nelc ++ 20standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
Questo porta un supporto limitato perc99Inizializzatori designati di. Questa limitazione è descritta come segue da C.1.7 [diff.decl] .4, dato:
struct A { int x, y; };
struct B { struct A a; };
Le seguenti inizializzazioni designate, valide in C, sono limitate in C ++:
struct A a = { .y = 1, .x = 2 }
non è valido in C ++ perché i designatori devono apparire nell'ordine di dichiarazione dei membri dati
int arr[3] = { [1] = 5 }
non è valido in C ++ perché l'inizializzazione designata dall'array non è supportata
struct B b = {.a.x = 0}
non è valido in C ++ perché i designatori non possono essere annidati
struct A c = {.x = 1, 2}
non è valido in C ++ perché tutti o nessuno dei membri di dati deve essere inizializzato dai designatori
Per c ++ 17 e in precedenza Boost lo ha effettivamente versioni supportano inizializzatori designati e sono state presentate numerose proposte per aggiungere supporto aC ++standard, ad esempio: n4172 e la proposta di Daryle Walker di aggiungere una designazione agli inizializzatori . Le proposte citano l'attuazione dic99Gli inizializzatori designati di Visual C ++, gcc e Clang affermano:
Riteniamo che le modifiche saranno relativamente semplici da implementare
Ma il comitato standard respinge ripetutamente tali proposte , affermando:
EWG ha riscontrato vari problemi con l'approccio proposto e non ha ritenuto fattibile provare a risolvere il problema, poiché è stato provato molte volte e ogni volta ha fallito
I commenti di Ben Voigt mi hanno aiutato a vedere i problemi insormontabili con questo approccio; dato:
struct X {
int c;
char a;
float b;
};
In quale ordine dovrebbero essere chiamate queste funzioni c99: struct X foo = {.a = (char)f(), .b = g(), .c = h()}
? Sorprendentemente, inc99:
L'ordine di valutazione delle sottoespressioni in qualsiasi inizializzatore è in sequenza indeterminata [ 1 ]
(Visual C ++, gcc e Clang sembrano avere un comportamento concordato in quanto effettueranno tutte le chiamate in questo ordine :)
h()
f()
g()
Ma la natura indeterminata dello standard significa che se queste funzioni avessero un'interazione, anche lo stato del programma risultante sarebbe indeterminato e il compilatore non ti avviserebbe : c'è un modo per essere avvisati del comportamento anomalo degli inizializzatori designati?
C ++ non hanno requisiti rigorosi di inizializzazione-list 11.6.4 [dcl.init.list] 4:
All'interno della lista di inizializzatori di una lista di inizializzazione con parentesi graffe, le clausole di inizializzazione, comprese quelle risultanti dalle espansioni di pacchetto (17.5.3), vengono valutate nell'ordine in cui appaiono. Cioè, ogni calcolo di valore ed e ff etto laterale associato a una data clausola di inizializzazione viene sequenziato prima di ogni calcolo di valore ed effetto collaterale associato a qualsiasi clausola di inizializzazione che lo segue nell'elenco separato da virgole dell'elenco di inizializzatori.
Così C ++ il supporto avrebbe richiesto che fosse eseguito nell'ordine:
f()
g()
h()
Rompere la compatibilità con il precedente c99 implementazioni.
Come discusso in precedenza, questo problema è stato aggirato dalle limitazioni sugli inizializzatori designati accettatic ++ 20. Forniscono un comportamento standardizzato, garantendo l'ordine di esecuzione degli inizializzatori designati.