2015-12-28 11 views
6

Recentemente ho scoperto uno strano comportamento di clang e gcc. Ho uno struct (MyClass), che utilizza l'inizializzazione in-class per uno dei suoi membri (active):Perché clang e gcc gestiscono l'inizializzazione forzata delle strutture con l'inizializzazione in-class in modo diverso?

struct MyClass { 
    int something; 
    bool active = true; 
}; 

Ora cerco di brace inizializzare di questa classe.

Utilizzando clang, posso decidere se includere active nell'elenco di inizializzazione (MyClass a = { 42, true};) o meno (MyClass a = { 42 };).

Tuttavia, utilizzando gcc, il mio codice viene compilato solo se non includo active. Altrimenti, verrà visualizzato il seguente errore del compilatore:

error: could not convert ‘{42, true}’ from ‘<brace-enclosed initializer list>’ to ‘MyClass’ 

È un errore? Cosa dice lo standard al riguardo? Che dire di VSC++? Quale strada consiglieresti come soluzione portatile?

Testato utilizzando gcc 4.9 e clang 3.5 su Debian Linux.

+2

Stai compilando in modalità C++ 14 per entrambi? – juanchopanza

+0

Sì, lo so. Ho anche abilitato tutti gli avvisi '-Wall', ma non ne ho ricevuto uno. – user3684240

+2

In C++ 11 una classe con [inizializzatori di membri in-classe non statici non è un aggregato] (http://stackoverflow.com/q/27118535/1708801) e quindi non funzionerà in modalità C++ 11 ma dovrebbe riuscire in modalità C++ 14 per entrambi. Come noto nella mia [risposta] (http://stackoverflow.com/a/27118551/1708801) alla domanda collegata gcc non ha supportato questo fino alla 5.0. –

risposta

8

Il comportamento di questo codice è cambiato tra C++ 11 e C++ 14.

In C++ 11 la presenza di = true indica che la classe non era un aggregato. Pertanto non è possibile utilizzare l'inizializzazione aggregata.

In C++ 14 la classe è ancora un aggregato, quindi è possibile utilizzare nuovamente l'inizializzazione di aggregazione.

La differenza tra i compilatori può essere spiegata con uno più recente dell'altro. Usando compiler explorer vedo che gcc 4.9.x si sbaglia, ma questo è corretto in gcc 5.1.

+0

L'utilizzo di clang in modalità C++ 11 supporta questa ipotesi. Si lamenta delle stesse cose di gcc. – user3684240

+0

La mia ipotesi è che questo sia tecnicamente un bug in modalità C++ 11 in clang - anche se uno è per lo più innocuo a meno che non si stia cercando un errore specifico quando viene utilizzato questo costrutto. –

+0

@MatsPetersson sembra corretto in clang e bug in g ++ –

Problemi correlati