2014-06-18 14 views
14

Perché gcc lancia un hissy fit se l'ordine dell'elenco di inizializzazione non corrisponde all'ordine delle variabili nella classe?Perché l'ordine di elenco inizializzatore deve corrispondere all'ordine di dichiarazione membro membro?

class myClass 
{ 
public: 
    int A; 
    int B; 
    myClass(); 
}; 

myClass::myClass() : 
B(1), 
A(2) 
{} 

si traducono in:

file.h:274: warning: 'myClass::A' will be initialized after 
file.h:273: warning: 'int myClass::B 
file.cpp:581: warning: when initialized here 

v'è alcuna ragione specifica per cui viene emesso questo tipo di avvertimento? Ci sono dei rischi associati all'inizializzazione delle variabili di una classe in ordine diverso da come sono definiti all'interno della classe?

(nota, c'è a question che tocca l'argomento, ma le risposte sono più o meno "perché dovrebbe essere così", senza dare alcuna spiegazione razionale per perché dovrebbe essere ordinato, o che cosa c'è di sbagliato con questo essere fuori order - Mi piacerebbe sapere perché esiste una restrizione del genere - qualcuno potrebbe dare un esempio in cui potrebbe ritorcersi contro?)

+0

@ShafikYaghmour: La norma non costituiscono restrizioni in quanto tale è un capriccio della sua scrittori. Ogni restrizione è il risultato di alcune considerazioni. Quindi, no, "perché lo standard dice così" non è una risposta sufficiente, di gran lunga. Certo alcune decisioni dello standard potrebbero essere discutibili o completamente errate - ma anche questi problemi ed errori derivano da certe origini. –

+2

Quindi forse la tua domanda dovrebbe essere "Perché l'ordine di inizializzazione è l'ordine della dichiarazione?" invece di chiedere informazioni sull'avviso. – dyp

+1

_ "C'è qualche ragione specifica per cui viene emesso questo tipo di avviso?" _ -Una ragione è di aiutarti. –

risposta

13

L'avviso sta tentando di impedire situazioni in cui si potrebbe fare affidamento sull'ordinamento sbagliato dei membri dati. Diciamo che pensa B viene inizializzato prima di A, e poi si fa qualcosa di simile:

myClass::myClass() : 
B(42), A(B) {} 

Qui, hanno undefined comportamento perché si sta leggendo da un non inizializzata B.

+0

Questo non risponde alla domanda, perché _IF_ era permesso specificare l'inizializzazione [lista] in qualsiasi ordine, quindi quello che hai scritto qui, cioè B prima di A e A in base a B, andrebbe bene. Essenzialmente ci hai detto solo che lo standard dice che l'inizializzazione dei membri dei dati non statici avviene nell'ordine in cui i membri sono stati dichiarati, senza dare alcuna logica dietro quella decisione. –

+0

@DanielGoldfarb La domanda non è chiedere * perché * lo standard specifica un certo ordine di inizializzazione di membri di dati non statici. Si chiede perché un'implementazione emetta un avvertimento in una determinata situazione e ho risposto a questa domanda. – juanchopanza

+1

Forse sto leggendo male. So che la domanda inizia a chiedere informazioni sul compilatore, ma c'è dell'altro. "Ci sono dei rischi ... ordine diverso da quello che sono definiti ..." E vedi la "nota", alla fine della domanda, che indica che affermare che lo standard dice così non fornisce una motivazione per lo standard. La tua risposta _segue_ fornisce una motivazione per l'avvertimento, e fa un buon punto; ma a me sembra che non risponda (per citare la nota alla fine della domanda) "perché dovrebbe essere ordinato" in primo luogo. Imho, la risposta di Shafik Yaghmour è più completa. –

2

L'ordine dell'elenco di inizializzazione è NON. La dichiarazione dei membri nell'intestazione della classe definisce l'ordine di inizializzazione.

Questo è di progettazione e richiesto in quanto si potrebbero avere più sensori che hanno ordini di lista di iniziazione completamente diversi.

Così i vostri membri saranno SEMPRE essere inizializzati nell'ordine di dichiarazione.

+0

* Questo è di progettazione e richiesto * => e perché è un problema? Perché ogni costruttore non è in grado di inizializzare il membro nell'ordine in cui è richiesto? –

+0

Vedere http://stackoverflow.com/questions/4037219/order-of-execution-in-constructor-initialization-list. Poiché non ci sono più sensori, la de-inizializzazione deve avvenire nell'ordine inverso dell'inizializzazione. – Samuel

+1

Lo so, ti stavo solo sondando la tua risposta per includere la giustificazione del "richiesto" nella tua risposta. A proposito, questo è completamente arbitrario; Il C++ ha fatto una scelta esplicita che l'ordine di distruzione sarebbe * sempre * il rovescio dell'ordine di costruzione, e la memorizzazione dell'ordine di costruzione non è stata ritenuta utile (non pagare per ciò che non è necessario + modello di compilazione separato), quindi entrambi l'ordine di costruzione e l'ordine di distruzione sono corretti. Altre alternative avrebbero potuto essere utilizzate. –

14

L'avviso indica che indipendentemente dall'ordine utilizzato nell'elenco di inizializzazione del costruttore, lo standard richiede che i membri di dati non statici vengano inizializzati nell'ordine in cui sono stati dichiarati. Possiamo vedere questo andando alla sezione draft C++ standard12.6.2inizializzazione basi e membri paragrafo che dice:

In un costruttore non delegare, procede di inizializzazione del seguente ordine:

e include:

Quindi, i membri di dati non statici vengono inizializzati nell'ordine in cui erano dichiarato nella definizione della classe (di nuovo indipendentemente dall'ordine degli inizializzatori di mem ).

Perché lo standard richiede questo?Siamo in grado di trovare una spiegazione razionale per questo in carta The Evolution of C++: 1985 to 1989 da Bjarne Stroustrup nella sezione 6 si dice:

L'inizializzazione avviene in ordine di dichiarazione nella classe con classi base inizializzate prima che i membri,

[ ...]

Il motivo per cui si ignora l'ordine degli inizializzatori è quello di preservare l'ordinamento FIFO normale delle chiamate del costruttore e del distruttore. Permettere due costruttori di utilizzare diversi ordini di inizializzazione delle basi e membri sarebbe vincolare le implementazioni di utilizzare più strategie costosi più dinamico e

Problemi correlati