2014-12-20 16 views
6

Si consideri il codice:discrepanza tra clang e g ++ nel trattare con const oggetti

struct Foo 
{ 
    int x = 10; 
}; 

int main() 
{ 
    const Foo foo; 
} 

Compila sotto g ++ http://coliru.stacked-crooked.com/a/99bd8006e10b47ef, tuttavia sputa un errore sotto clang ++ http://coliru.stacked-crooked.com/a/93f94f7d9625b579:

error: default initialization of an object of const type 
     'const Foo' requires a user-provided default constructor 

Non sono sicuro chi è giusto qui. Perché abbiamo bisogno di un ctor predefinito poiché eseguiamo l'inizializzazione in classe?

+0

Ecco una grande risposta. http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a – Thellimist

+2

Questo è [CWG problema 253] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253). –

+0

@Furkan, nota che so perché la regola è così com'è, non capisco perché è applicabile nel mio caso, poiché il mio oggetto è perfettamente ben definito in fase di runtime. – vsoftco

risposta

7

Un oggetto di tipo classe può essere inizializzato solo se dispone di un costruttore predefinito fornito dall'utente. Da [dcl.init]/7:

Se un programma richiede l'inizializzazione predefinita di un oggetto di un tipo const qualificato T, T sarà un tipo di classe con un costruttore di default fornito dall'utente.

La vostra classe Foo non dispone di quello; la presenza di un inizializzatore controvento o uguale non crea un costruttore predefinito fornito dall'utente. Piuttosto, la classe ha un definito implicitamente costruttore predefinito, la cui azione incorpora l'inizializzazione come richiesto dall'inizializzatore contraccolpo-o-equals. (Clang ha ragione.)

([dcl.fct.def.default], in particolare il paragrafo 5, riporta le definizioni di "fornito dall'utente", "esplicitamente predefinito", "implicitamente dichiarato" e "definito come eliminato ." l'intera sezione vale la pena conoscere)

Tra l'altro, è facile evitare il default-inizializzazione in C++ 11:.

const Foo foo {}; // hunky-dory 
+0

** + 1 ** per "hunky dory". :) –

+0

Che differenza fa '{}' ?? – 0x499602D2

+0

@ 0x499602D2 inizializza il valore, quindi il compilatore è felice che in un 'const' tutto sia inizializzato. Immagino che il problema nel mio caso sia quando si ha una variabile 'y' aggiuntiva che non si inizializza in classe. Il C++ standard ha deciso che non si preoccuperà di controllare che tutti i membri siano inizializzati in classe, quindi la vecchia regola è ancora applicabile. – vsoftco

3

clang sembra essere giusto in base a 8,5 [dcl.init ] paragrafo 7 ultima frase:

Se un programma richiede l'inizializzazione predefinita di un oggetto di tipo constT, T deve essere un tipo di classe con un costruttore predefinito fornito dall'utente.

Chiaramente, il tipo non ha un costruttore predefinito fornito dall'utente.

Problemi correlati