2013-08-19 60 views
14

Nota: stiamo parlando di compilatori (presumibilmente) conformi a C++ 98, qui. Questa non è una domanda in C++ 11.C++ array-inizializzazione: si tratta di un bug o è corretto?

Abbiamo uno strano comportamento in uno dei nostri compilatori e non siamo sicuri se questo è ok o se questo è un bug del compilatore:

// 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 viene inizializzato come tale:

BBB bbb = {0} ; 

Ci aspettavamo che tutti i membri POD di BBB (inclusi m_d, la matrice di ints) fossero inizializzati a zero e che tutti i membri non POD di BBB venissero costruiti.

Questo ha funzionato sul compilatore nativo di AIX, su Linux/GCC-3.4, su Windows/VisualC++ ... Ma non su Solaris/SunStudio, dove solo i membri di non-array sono inizializzati a zero.

abbiamo fatto una piccola ricerca, nello standard C++ 98 (una bozza di documento), dove abbiamo trovato la seguente:

[12.6.1 - 2]

Quando un aggregato (se la classe o l'array) contiene membri di tipo classe ed è inizializzato da un elenco inizializzatore (8.5.1) racchiuso tra parentesi, ciascun membro è inizializzato in copia (vedere 8.5) dalla corrispondente espressione-assegnazione. Se nell'elenco di inizializzazione sono presenti meno inizializzatori rispetto ai membri dell'aggregato, ciascun membro non inizializzato in modo esplicito deve essere inizializzato automaticamente (8.5).

Poi:

[8.5 - 5]

a zero-inizializzare immagazzinaggio per un oggetto di tipo T significa:
- se T è un tipo scalare (3.9), la memorizzazione è impostata sul valore di 0 (zero) convertito in T;
- se T è un tipo di classe non di unione, lo spazio di archiviazione per ogni membro di dati non statici e ciascun sottoprogetto di classe base è inizializzato a zero;
- se T è un tipo di unione, la memoria per il suo primo membro di dati 89) è inizializzata a zero;
- se T è un tipo di matrice, la memorizzazione per ciascun elemento è inizializzata a zero;
- se T è un tipo di riferimento, non viene eseguita alcuna inizializzazione.

E poi:

Per default-inizializzare un oggetto di tipo T significa:
- se T è un non-POD tipo di classe (clausola 9), il costruttore di default per T è chiamato (e l'inizializzazione è mal formata se T non ha un costruttore predefinito accessibile);
- se T è un tipo di matrice, ogni elemento viene inizializzato di default;
- in caso contrario, la memorizzazione per l'oggetto è inizializzata a zero.

Il modo in cui l'ho letto: Studio Sole dovrebbe azzerare-inizializzare l'array di int (BBB :: m_d)

Cosa strana: se togliamo il costruttore di default da AAA, poi tutto a BBB è zero inizializzato.

DOMANDA: Il comportamento di SunStudio è standard quando non riesce a inizializzare a zero una matrice di interi di una struttura contenente un non POD? O questo è un bug del compilatore?

+4

sembra un bug per me. Cosa succede se scrivi 'BBB bbb = {0,0,0, {0}};' –

+10

Si tratta di un errore in Sun CC. La tua comprensione dello standard è corretta. –

+0

@JamesKanze: Non riesco davvero a mandare avanti i commenti, né a sceglierli come risposte ... non esitare a rispondere esaurientemente ... :-) – paercebal

risposta

2

È in effetti un bug con Sun/Solaris. Quello che hai scritto è davvero ciò che dovrebbe accadere e tu hai ragione con tutto ciò che scrivi.

1

Questo è chiaramente un errore in Sun CC. Lo standard è chiaro e la tua comprensione di ciò è corretta.

1

Sembra un bug - Non ho esperienza con i compilatori Solaris, ma tutti gli altri compilatori con cui ho lavorato consentiranno questo tipo di inizializzazione.

vorrei suggerire che il lavoro intorno al problema di essere più esplicito:

BBB bbb = {0, 0, 0, {0} }; 
Problemi correlati