Em 15 de julho de 17, P0329R4 foi aceito noc ++ 20padrão: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
Isso traz suporte limitado parac99Inicializadores designados de. Esta limitação é descrita a seguir por C.1.7 [diff.decl] .4, dado:
struct A { int x, y; };
struct B { struct A a; };
As seguintes inicializações designadas, que são válidas em C, são restritas em C ++:
struct A a = { .y = 1, .x = 2 }
é inválido em C ++ porque os designadores devem aparecer na ordem de declaração dos membros de dados
int arr[3] = { [1] = 5 }
é inválido em C ++ porque a inicialização designada por matriz não é compatível
struct B b = {.a.x = 0}
é inválido em C ++ porque os designadores não podem ser aninhados
struct A c = {.x = 1, 2}
é inválido em C ++ porque todos ou nenhum dos membros de dados devem ser inicializados por designadores
Para c ++ 17e Boost anterior, na verdade, tem suporte para inicializadores designados e houve inúmeras propostas para adicionar suporte aoc ++padrão, por exemplo: n4172 e a proposta de Daryle Walker para adicionar designação aos inicializadores . As propostas citam a implementação dec99Inicializadores designados da em Visual C ++, gcc e Clang, afirmando:
Acreditamos que as mudanças serão relativamente simples de implementar
Mas o comitê padrão rejeita repetidamente tais propostas , afirmando:
O EWG encontrou vários problemas com a abordagem proposta e não achou viável tentar resolver o problema, pois já foi tentado várias vezes e sempre falhou
Os comentários de Ben Voigt me ajudaram a ver os problemas intransponíveis dessa abordagem; dado:
struct X {
int c;
char a;
float b;
};
Em que ordem essas funções seriam chamadas em c99: struct X foo = {.a = (char)f(), .b = g(), .c = h()}
? Surpreendentemente, emc99:
A ordem de avaliação das subexpressões em qualquer inicializador é sequenciada indeterminadamente [ 1 ]
(Visual C ++, gcc e Clang parecem ter um comportamento acordado, pois todos farão as chamadas nesta ordem :)
h()
f()
g()
Mas a natureza indeterminada do padrão significa que, se essas funções tivessem qualquer interação, o estado do programa resultante também seria indeterminado, e o compilador não o avisaria : Existe uma maneira de ser avisado sobre o mau comportamento de inicializadores designados?
c ++ não têm requisitos de lista de inicializador rigorosas 11.6.4 [dcl.init.list] 4:
Na lista de inicializadores de uma lista de inicializações com chaves, as cláusulas inicializadoras, incluindo qualquer uma que resulte de expansões de pacote (17.5.3), são avaliadas na ordem em que aparecem. Ou seja, cada cálculo de valor e efeito colateral associado a uma determinada cláusula inicializadora é sequenciado antes de cada cálculo de valor e efeito colateral associado a qualquer cláusula inicializadora que o segue na lista separada por vírgulas da lista inicializadora.
assim c ++ o suporte teria exigido que fosse executado na ordem:
f()
g()
h()
Quebrando a compatibilidade com o anterior c99implementações.
Conforme discutido acima, este problema foi contornado pelas limitações dos inicializadores designados aceitos emc ++ 20. Eles fornecem um comportamento padronizado, garantindo a ordem de execução dos Inicializadores Designados.