2011-11-11 15 views
14

Questo compila perfettamente bene con l'attuale compilatore MSVC:inizializzata const

struct Foo 
{ 
} const foo; 

Tuttavia, non riesce a compilare con la g corrente ++ compiler:

error: uninitialized const 'foo' [-fpermissive] 
note: 'const struct Foo' has no user-provided default constructor 

Se fornisco un costruttore di default me ​​stesso, è works:

struct Foo 
{ 
    Foo() {} 
} const foo; 

È un altro caso di MSVC troppo permissivo o g ++ troppo rigido qui?

+0

Ottima domanda Mr Overflow. –

+0

Duplicati: http://stackoverflow.com/questions/5335836/why-a-const-object-of-an-empty-class-cant-be-created http://stackoverflow.com/questions/7411515/why- does-c-require-a-user-provided-default-constructor-to-default-construct-a, tra gli altri. – GManNickG

+0

Non riesco a riprodurlo su GCC 4.6.1, con qualsiasi opzione di dialetto. Funziona solo se installo una variabile membro (come 'int a;'), e l'errore è molto più accurato: ''const struct Foo' non ha un costruttore predefinito fornito dall'utente e il costruttore implicitamente definito non inizializza 'int Foo :: a'' –

risposta

13

Il C++ 03 standard:

8,5 [dcl.init] paragrafo 9

Se non inizializzatore è specificata per un oggetto e l'oggetto è di (possibilmente cv -qualificato) di tipo non POD (o sua matrice), l'oggetto deve essere inizializzato di default; se l'oggetto è di tipo const-qualified, il tipo di classe sottostante deve avere un costruttore predefinito dichiarato dall'utente.

Da quanto sopra l'errore in gcc sembra essere perfettamente valido.

+7

+1 per Mr I'm-a-Hash-Table-of-the-Standard :-) –

1

Non conosco il testo esatto dello standard, ma l'errore in g ++ sembra molto più ragionevole dell'opzione di non dire nulla. Considerate questo:

struct X { 
    int value; 
}; 
const X constant; // constant.value is undefined 

Non nel caso di un utente fornito costruttore di default (anche se non fa niente) il compilatore chiamata che il costruttore e l'oggetto sarà inizializzato (con qualsiasi definizione di inizializzato voi hanno implementato nel tuo costruttore).

3

[2003: 8.5/9]:Se non è specificato alcun inizializzatore di un oggetto, e l'oggetto è di (possibilmente cv-qualificata) non-POD classe tipo (o array loro), l'oggetto è predefinito inizializzata ; se l'oggetto è di tipo const-qualified, il tipo di classe sottostante deve avere un costruttore predefinito dichiarato dall'utente . Altrimenti, se nessun inizializzatore è specificato per un oggetto non statico, l'oggetto e i suoi sottooggetti, se , hanno un valore iniziale indeterminato; se l'oggetto o uno qualsiasi dei suoi sottooggetti sono di tipo const-qualified, il programma è mal formato.

E:

[n3290: 8.5/11]:Se non viene specificato di inizializzazione di un oggetto, l'oggetto è default-inizializzato; se l'inizializzazione non è eseguita, un oggetto con durata di archiviazione automatica o dinamica ha valore indeterminato . [Nota: Gli oggetti con memoria statica o con memorizzazione thread sono inizializzati a zero, vedere 3.6.2._ -end note_]

[n3290: 8.5/6]: Per default-inizializzare un oggetto di tipo T significa:

  • se T è un (possibilmente cv-qualificato) 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 è inizializzato di default;
  • in caso contrario, non viene eseguita alcuna inizializzazione.

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.

Quindi MSVC è più permissivo rispetto al mandato standard.

Problemi correlati