2012-06-05 20 views
7

Duplicar posible:
Can objects with private copy constructors be thrown?VS compilador podría tener acceso a la copia privada ctor

Como sé, cuando TROW objeto como valor, la copia debe ser creado. Por lo tanto, se debe llamar al constructor de copia si existe. Si copy ctor existe y es privado, esto debería causar un error de compilación. Aquí está el código de muestra

class Exception { 
public: 
Exception() { 
    cout << "Exception()" << endl; 
} 

~Exception() { 
    cout << "~Exception() " << endl; 
} 
private: 
Exception(const Exception &c) { 
     cout << "Exception(c)" << endl; 
    } 
}; 

Y el siguiente código debería llevar a un error de compilación.

try { 
     Exception local; 

     throw local; 
    } catch (...) { 
    } 

Pero tanto en VS 2005 como en VS 2008 compilaron exitosamente ese código y llamaron al ctor privado. ¿Me equivoco al decir que este es un comportamiento no estándar y es un error en el compilador?

+0

Hablé demasiado pronto. http://ideone.com/hXrJd –

+2

@Ation: VS solía ser el peor compilador de C++ compatible con el estándar entre los principales (gcc, icc, comeau, etc.). Sus seguidores dicen que es mucho mejor ahora, personalmente dejé de usarlo. –

Respuesta

0

Voy a salir en una extremidad aquí y decir que esto es probablemente un error MSVC 10 legítimo. Sin embargo, no puedo encontrar una referencia para esto.

Aquí es un instrumento de prueba:

#include <cstdlib> 
#include <string> 
#include <iostream> 
#include <iomanip> 
using namespace std; 

class Exception { 
public: 
Exception() { 
    cout << "Exception()" << endl; 
} 

~Exception() { 
    cout << "~Exception() " << endl; 
} 
private: 
Exception(const Exception &c) { 
     cout << "Exception(c)" << endl; 
    } 
}; 

int main() 
{ 
    try { 
     Exception local; 

     int n = 42; 

     throw local; 
    } catch (...) 
    { 
    } 
} 

Este código debe dejar de compilar por la razón de nota - el constructor de copia es private y se llama desde fuera del contexto de la clase.

Este código se compila con éxito en MSVC 10 y MSVC 11 Dev Preview.

4.4.4 GCC bajo RHEL6.2 emite:

[[email protected] ~]$ gcc --version 
gcc (GCC) 4.4.4 20100726 (Red Hat 4.4.4-13) 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
[[email protected] ~]$ gcc hack.cpp 
hack.cpp: In function ‘int main()’: 
hack.cpp:17: error: ‘Exception::Exception(const Exception&)’ is private 
hack.cpp:29: error: within this context 
[[email protected] ~]$ 
0

La norma dice que una excepción debe ser copiable debido tiro puede hacer una copia. Ha hecho que el constructor de copia sea privado, por lo que no debería compilarse.

No obstante, no indica que la implementación de throw es requiere para hacer una copia, de hecho, puede ser eliminada o en C++ 11 incluso movida. Entonces, aunque MSVC debería negarse a compilar el código con el argumento de que no cumple con los estándares, aún lo hace, porque funcionará con la forma de hacer las cosas de MSVC.

Esto no es probable que sea un error, sino simplemente un caso de VC que no cumple con el estándar.

+0

¿Cómo es no cumplir * no * un error? –

+1

@MarkB Supongo que eso depende de cómo se defina un error. Aquí, me refiero al punto que parece intencional por parte de Microsoft. Hablando desde la experiencia, este es exactamente el tipo de cosas en las que serían "laxas". –

+1

La norma establece explícitamente que incluso cuando se eliminan las copias, el constructor de copia debe estar disponible y ser accesible. No veo ninguna manera de interpretar este comportamiento como un error. –

Cuestiones relacionadas