El 15 de julio de 2017 P0329R4 fue aceptado en elc ++ 20estándar: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
Esto brinda soporte limitado parac99Inicializadores designados. Esta limitación se describe como sigue en C.1.7 [diff.decl] .4, dado:
struct A { int x, y; };
struct B { struct A a; };
Las siguientes inicializaciones designadas, que son válidas en C, están restringidas en C ++:
struct A a = { .y = 1, .x = 2 }
no es válido en C ++ porque los designadores deben aparecer en el orden de declaración de los miembros de datos
int arr[3] = { [1] = 5 }
no es válido en C ++ porque la inicialización designada por matriz no es compatible
struct B b = {.a.x = 0}
no es válido en C ++ porque los designadores no se pueden anidar
struct A c = {.x = 1, 2}
no es válido en C ++ porque todos o ninguno de los miembros de datos deben ser inicializados por designadores
por c ++ 17y Boost anterior en realidad tiene soporte para Intializadores designados y ha habido numerosas propuestas para agregar soporte a lac ++estándar, por ejemplo: n4172 y la propuesta de Daryle Walker para agregar una designación a los inicializadores . Las propuestas citan la implementación dec99Inicializadores designados en Visual C ++, gcc y Clang que afirman:
Creemos que los cambios serán relativamente sencillos de implementar.
Pero el comité estándar rechaza repetidamente tales propuestas , afirmando:
EWG encontró varios problemas con el enfoque propuesto y no pensó que fuera factible intentar resolver el problema, ya que se ha intentado muchas veces y cada vez ha fallado.
Los comentarios de Ben Voigt me han ayudado a ver los problemas insuperables con este enfoque; dado:
struct X {
int c;
char a;
float b;
};
¿En qué orden se llamarían estas funciones en c99: struct X foo = {.a = (char)f(), .b = g(), .c = h()}
? Sorprendentemente, enc99:
El orden de evaluación de las subexpresiones en cualquier inicializador tiene una secuencia indeterminada [ 1 ]
(Visual C ++, gcc y Clang parecen tener un comportamiento acordado, ya que todos realizarán las llamadas en este orden :)
h()
f()
g()
Pero la naturaleza indeterminada del estándar significa que si estas funciones tuvieran alguna interacción, el estado del programa resultante también sería indeterminado, y el compilador no le advertiría : ¿Hay alguna manera de recibir una advertencia sobre los inicializadores designados que se comportan mal?
c ++ no tienen requisitos estrictos de inicialización de listas 11.6.4 [dcl.init.list] 4:
Dentro de la lista de inicialización de una lista de inicialización entre llaves, las cláusulas de inicialización, incluidas las que resultan de las expansiones de paquetes (17.5.3), se evalúan en el orden en que aparecen. Es decir, cada cálculo de valor y efecto secundario asociado con una cláusula inicializadora dada se secuencia antes de cada cálculo de valor y efecto secundario asociado con cualquier cláusula inicializador que le siga en la lista separada por comas de la lista de inicializadores.
Entonces c ++ El soporte habría requerido que esto se ejecutara en el orden:
f()
g()
h()
Rompiendo la compatibilidad con anteriores c99implementaciones.
Como se discutió anteriormente, este problema ha sido eludido por las limitaciones en Inicializadores Designados aceptados enc ++ 20. Proporcionan un comportamiento estandarizado, garantizando el orden de ejecución de los Inicializadores Designados.