c ++ array zero-initialization: ¿Es esto un error, o es correcto?
Nota: Estamos hablando de (supuestamente) compiladores compatibles con C ++ 98, aquí. Esta no es una pregunta de C ++ 11
Tenemos un comportamiento extraño en uno de nuestros compiladores y no estamos seguros de si esto está bien o si se trata de un error del compilador:
// This struct has a default constructor
struct AAA
{
AAA() : value(0) {}
int value ;
} ;
// This struct has a member of type AAA and an array of int, both surrounded
// by ints
struct BBB
{
int m_a ;
AAA m_b ;
int m_c ;
int m_d[42] ;
} ;
Cuando BBB se inicializa como tal:
BBB bbb = {0} ;
Esperamos que todos los miembros POD de BBB (incluido m_d, la matriz de entradas) se inicialicen con cero, y que se construyan todos los miembros que no son POD de BBB.
Esto funcionó en el compilador nativo de AIX, en Linux / GCC-3.4, en Windows / VisualC ++ ... Pero no en Solaris / SunStudio, donde solo los miembros que no forman matrices tienen inicialización cero.
Hicimos una pequeña investigación, en el estándar C ++ 98 (un borrador de documento), donde encontramos lo siguiente:
[12.6.1 - 2]
Cuando un agregado (ya sea clase o matriz) contiene miembros de tipo de clase y se inicializa mediante una lista de inicializadores (8.5.1) entre llaves, cada uno de dichos miembros se inicializa con copia (ver 8.5) mediante la expresión-asignación correspondiente.Si hay menos inicializadores en la lista de inicializadores que miembros del agregado, cada miembro que no se inicialice explícitamente se inicializará por defecto (8.5).
Entonces:
[8.5 - 5]
A cero inicializar almacenamiento para un objeto de tipo T significa:
— si T es un tipo escalar (3.9), el almacenamiento se establece en el valor de 0 (cero) convertido a T;
- si T es un tipo de clase no sindicalizada, el almacenamiento para cada miembro de datos no estáticos y cada subobjeto de clase base se inicializa con cero;
- si T es un tipo de unión, el almacenamiento para su primer miembro de datos 89) se inicializa en cero;
- si T es un tipo de matriz, el almacenamiento para cada elemento se inicializa con cero;
- Si T es un tipo de referencia, no se realiza ninguna inicialización.
Y entonces:
Para inicializar por defecto un objeto de tipo T significa:
- si T es un tipo de clase no POD (cláusula 9), se llama al constructor predeterminado para T (y la inicialización no es correcta si T no tiene un constructor por defecto accesible);
— si T es un tipo de matriz, cada elemento se inicializa por defecto;
— de lo contrario, el almacenamiento para el objeto es cero inicializado.
La forma en que lo leí: SunStudio debería inicializar en cero la matriz de entradas (BBB :: m_d)
Cosa extraña: si eliminamos el constructor predeterminado de AAA, entonces todo en BBB tiene cero inicialización.
PREGUNTA: ¿El comportamiento de SunStudio es estándar cuando falla al inicializar en cero una matriz de entradas de una estructura que contiene un POD no? ¿O es esto un error de compilación?