c ++ array zero-initialization: Isso é um bug ou está correto?

Nota: Estamos falando sobre (supostamente) compiladores compatíveis com C ++ 98, aqui. Esta não é uma questão do C ++ 11.

Nós temos um comportamento estranho em um de nossos compiladores e não temos certeza se isso é Ok ou se é um erro do 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] ;
} ;

Quando BBB é inicializado como tal:

BBB bbb = {0} ;

Esperávamos que todos os membros do POD de BBB (incluindo m_d, o array de ints) fossem inicializados com zero, e todos os membros não-POD de BBB fossem construídos.

Isso funcionou no compilador nativo do AIX, no Linux / GCC-3.4, no Windows / VisualC ++ ... Mas não no Solaris / SunStudio, onde apenas os membros que não são matrizes são inicializados com zero.

Fizemos uma pequena pesquisa, no padrão C ++ 98 (um documento de rascunho), onde encontramos o seguinte:

[12.6.1 - 2]

Quando um agregado (seja classe ou array) contém membros do tipo de classe e é inicializado por uma lista de inicializadores de chaves (8.5.1), cada um desses membros é inicializado com cópia (ver 8.5) pela expressão de atribuição correspondente.Se houver menos inicializadores na lista de inicializadores do que membros do agregado, cada membro não inicializado explicitamente será inicializado por padrão (8.5).

Então:

[8,5-5]

Para inicializar zero armazenamento para um objeto do tipo T significa:
— se T é um tipo escalar (3.9), o armazenamento é configurado para o valor de 0 (zero) convertido para T;
- se T for um tipo de classe não-union, o armazenamento para cada membro de dados não estáticos e cada subobjeto de classe base será inicializado com zero;
- se T é um tipo de união, o armazenamento para seu primeiro membro de dados 89) é inicializado com zero;
- se T for um tipo de matriz, o armazenamento de cada elemento será inicializado com zero;
- se T é um tipo de referência, nenhuma inicialização é executada.

E depois:

Para inicializar por padrão um objeto do tipo T significa:
- se T é um tipo de classe não-POD (cláusula 9), o construtor padrão para T é chamado (e a inicialização é mal formada se T não tiver nenhum construtor padrão acessível);
— se T é um tipo de matriz, cada elemento é inicializado por padrão;
— caso contrário, o armazenamento para o objeto será inicializado com zero.

A maneira que eu li: SunStudio deve inicializar zero a matriz de ints (BBB :: m_d)

Coisa estranha: se removermos o construtor padrão do AAA, tudo em BBB será inicializado com zero.

PERGUNTA: O comportamento do SunStudio é padrão quando ele falha ao inicializar zero uma matriz de ints de uma estrutura que contém um não-POD? Ou isso é um erro de compilador?

questionAnswers(3)

yourAnswerToTheQuestion