2012-10-09 7 views
8

Eventuali duplicati:
std::string x(x);Perché si può chiamare un costruttore di copia che passa nell'oggetto che si sta costruendo? (C++) (gcc)

class A {}; 

int main() { 

    A a(a); 
} 

Questo compila.

gcc (GCC) 4.7.2 20.120.921 (Red Hat 4.7.2-2)
g++ -o main main.cpp -Wall -w -ansi

ricevo nessun avviso.

Perché questo sembra essere C++ valido?
Questo è menzionato ovunque nello standard?
Sono presenti contrassegni di avviso che possono segnalare questo per gcc?

Quando la classe ha dati membro, i dati finiscono casualmente.
esempio:

#include <iostream> 

class A { 

public: 
    int i; 
    A() : i{6} {} 
}; 

int main() { 

    A a(a); 
    std::cout << a.i << '\n'; 
} 

uscita: -482728464

Che cosa sta succedendo qui? Inoltre, come posso evitare di farlo accidentalmente? - È possibile renderlo un errore del compilatore?

+2

Nota l'esempio più semplice, 'int i = i;'. – GManNickG

+1

Clang 3.2 ha recentemente rivisto il proprio algoritmo per rilevare tali casi, è possibile controllare il file [uninitialized.cpp] (http://llvm.org/svn/llvm-project/cfe/trunk/test/SemaCXX/uninitialized.cpp) dalla suite di test per vedere tutti i casi in cui avverte. Tieni presente che con gcc, gli avvisi * non inizializzati * sono potenzialmente legati al livello di ottimizzazione e possono essere attivati ​​solo per le build 'O1' o' O2'. –

risposta

10

(§ 3.3.2/1) Il punto di dichiarazione per un nome è immediatamente dopo la sua completa dichiaratore (clausola 8) e prima della sua initializer (se presente), ad eccezione di quanto indicato di seguito. [Esempio:

int x = 12; 
{ int x = x; } 

Qui la seconda x viene inizializzata con il proprio valore (indeterminato). -end esempio]

Questo vale per i tipi definiti dall'utente, come ad esempio il class A. Il costruttore di copie utilizzato è quello predefinito, generato automaticamente dal compilatore.