c ++ tablica zero inicjalizacji: czy jest to błąd, czy jest to poprawne?
Uwaga: Mówimy tutaj o (podobno) kompilatorach zgodnych z C ++ 98, tutaj. To nie jest pytanie C ++ 11.
Mamy dziwne zachowanie w jednym z naszych kompilatorów i nie jesteśmy pewni, czy jest to OK, czy jest to błąd kompilatora:
// 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] ;
} ;
Kiedy BBB jest zainicjowane jako takie:
BBB bbb = {0} ;
Spodziewaliśmy się, że wszystkie elementy POD BBB (w tym m_d, tablica intów) zostaną zainicjowane zerami, a wszystkie elementy BBB nie-POD zostaną skonstruowane.
To działało na rodzimym kompilatorze AIX, na Linuksie / GCC-3.4, na Windows / VisualC ++ ... Ale nie na Solaris / SunStudio, gdzie tylko elementy nie będące tablicami są inicjowane zerowo.
Zrobiliśmy trochę badań w standardzie C ++ 98 (szkic dokumentu), gdzie znaleźliśmy następujące:
[12.6.1 - 2]
Gdy agregat (niezależnie od tego, czy jest to klasa, czy tablica) zawiera elementy typu class i jest inicjowany przez listę inicjalizującą z nawiasami klamrowymi (8.5.1), każdy taki element jest inicjowany przez kopiowanie (patrz 8.5) przez odpowiednie wyrażenie przypisania.Jeśli w liście inicjalizującej jest mniej inicjalizatorów niż członków agregatu, każdy element nie zainicjowany jawnie powinien zostać zainicjowany domyślnie (8.5).
Następnie:
[8,5 - 5]
Aby zainicjować zero przechowywanie obiektu typu T oznacza:
— jeśli T jest typem skalarnym (3.9), pamięć jest ustawiona na wartość 0 (zero) konwertowaną na T;
- jeśli T jest typem klasy niezwiązanej, pamięć dla każdego niestatycznego elementu danych i każdego podobiektu klasy bazowej jest inicjowana zerowo;
- jeśli T jest typem unii, pamięć dla jego pierwszego elementu danych 89) jest inicjowana zerowo;
- jeśli T jest typem tablicy, pamięć dla każdego elementu jest inicjowana zerowo;
- jeśli T jest typem odniesienia, nie jest przeprowadzana inicjalizacja.
I wtedy:
Aby zainicjować domyślnie obiekt typu T oznacza:
- jeśli T jest typem klasy innej niż POD (klauzula 9), wywoływany jest domyślny konstruktor dla T (i inicjalizacja jest nieprawidłowa, jeśli T nie ma dostępnego domyślnego konstruktora);
— jeśli T jest typem tablicy, każdy element jest inicjowany domyślnie;
— w przeciwnym razie pamięć obiektu zostanie zainicjowana zero.
Sposób, w jaki to przeczytałem: SunStudio powinno zerować inicjalizację tablicy intów (BBB :: m_d)
Dziwna rzecz: jeśli usuniemy domyślny konstruktor z AAA, to wszystko w BBB jest inicjowane zerowo.
PYTANIE: Czy standard zachowania SunStudio, gdy nie udaje mu się zerować inicjalizacji tablicy intów struktury zawierającej non-POD? Czy jest to błąd kompilatora?