2012-06-05 18 views
7

Eventuali duplicati:
Can objects with private copy constructors be thrown?VS compilatore potrebbe accedere copia privata ctor

Per quanto ne so, quando si Trow oggetto come valore, deve essere creato copia. Quindi il costruttore di copia dovrebbe essere chiamato se esiste. Se copy ctor esiste ed è privato, ciò dovrebbe causare errori di compilazione. Ecco il codice di esempio

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

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

E la prossima codice dovrebbe portare ad errore di compilazione.

try { 
     Exception local; 

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

Ma sia in VS 2005 e VS 2008 con successo compilare il codice e chiamare ctor privato. Ho sbagliato che questo comportamento non è standard ed è un errore nel compilatore?

+0

Ho parlato troppo presto. http://ideone.com/hXrJd –

+2

@Azione: VS era il peggiore compilatore C++ conforme agli standard tra i più importanti (gcc, icc, comeau, ecc.). I suoi sostenitori dicono che è molto meglio ora, personalmente ho smesso di usarlo. –

risposta

0

Ho intenzione di uscire su un arto qui e dire che questo è probabilmente un bug MSVC 10 legittimo. Non riesco a trovare un riferimento per questo, tuttavia.

Ecco un test harness:

#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 (...) 
    { 
    } 
} 

Questo codice non dovesse compilare per la ragione si nota - il costruttore di copia è private e di essere chiamato dal di fuori del contesto della classe.

Questo codice viene compilato correttamente in MSVC 10 e MSVC 11 Dev Preview.

GCC 4.4.4 sotto RHEL6.2 emette:

[[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

Lo standard dice che un'eccezione deve essere copiabile perché tiro può fare una copia. Hai reso privato il costruttore della copia, quindi non dovrebbe essere compilato.

Tuttavia, non è detto che l'implementazione del lancio sia richiesta per fare una copia - anzi, può essere elidata o anche in C++ 11 spostata. Quindi, anche se MSVC dovrebbe rifiutarsi di compilare il codice sulla base del fatto che non è conforme agli standard, lo fa ancora, perché funzionerà con il modo in cui MSVC fa le cose.

Questo non è probabilmente un bug, ma piuttosto solo un caso di VC non conforme allo standard.

+0

Come è non conforme * non * un bug? –

+1

@ MarkB Suppongo che dipenda da come si definisce un bug. Qui, mi riferisco al punto che sembra intenzionale da parte di Microsoft. Parlando dall'esperienza, questo è esattamente il tipo di cosa su cui sarebbero "rilassati". –

+1

Lo standard afferma esplicitamente che anche quando le copie vengono eliminate, il costruttore della copia deve essere ancora disponibile e accessibile. Non riesco a vedere alcun modo per interpretare questo comportamento come un non bug. –

Problemi correlati