2012-10-09 17 views
8

Duplicar posible:
std::string x(x);¿Por qué puede llamar a un constructor de copia que pasa en el objeto que está construyendo? (C++) (gcc)

class A {}; 

int main() { 

    A a(a); 
} 

Esto compila.

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

recibo ninguna advertencia.

¿Por qué esto parece ser válido C++?
¿Se menciona esto en algún lugar de la norma?
¿Hay indicadores de advertencia que puedan informar esto para gcc?

Cuando la clase tiene datos de miembros, los datos terminan al azar.
ejemplo:

#include <iostream> 

class A { 

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

int main() { 

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

de salida: -482728464

¿Qué está pasando aquí? Además, ¿cómo puedo evitar que accidentalmente haga esto? - ¿Es posible convertirlo en un error de compilación?

+2

Tenga en cuenta el ejemplo más simple, 'int i = i;'. – GManNickG

+1

Clang 3.2 ha revisado recientemente su algoritmo para detectar dichos casos, puede consultar el archivo [uninitialized.cpp] (http://llvm.org/svn/llvm-project/cfe/trunk/test/SemaCXX/uninitialized.cpp) desde el banco de pruebas para ver todos los casos en los que advierte. Tenga en cuenta que con gcc, las advertencias * no inicializadas * están potencialmente relacionadas con el nivel de optimización y solo pueden activarse para compilaciones 'O1' o' O2'. –

Respuesta

10

(§ 3.3.2/1) El punto de la declaraciónde un nombre es inmediatamente después de su completa declarador (Cláusula 8) y antes de su inicializador (si lo hay), excepto como se indica a continuación. [Ejemplo:

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

Aquí la segunda x se inicializa con su propio valor (indeterminado). ejemplo -end]

Esto se aplica a los tipos definidos por el usuario, como su class A, también. El constructor de copia utilizado es el predeterminado, autogenerado por el compilador.

Cuestiones relacionadas