Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can objects with private copy constructors be thrown?

I've come across some exceptions issue that is unclear to me. In C++, when an object is thrown it is first copied to a temporary object, and the temporary object is then passed to the catching code. The copy involves the use of the object's class copy constructor. AFAIK, this means that if a class has a private copy constructor, it can't be used as an exception. However, in VS2010, the following code compiles and runs:

class Except
{
    Except(const Except& other) { i = 2; }
public:
    int i;
    Except() : i(1) {}
};

int main()
{
    try
    {
        Except ex1;
        throw ex1;          // private copy constructor is invoked
    }
    catch (Except& ex2)
    {
        assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2
    }
    return 0;
}

Is this legal?

like image 325
eran Avatar asked Apr 11 '12 09:04

eran


2 Answers

It's not legal. Standard 15.1/5

If the use of the temporary object can be eliminated without changing the meaning of the program except for the execution of constructors and destructors associated with the use of the temporary object (12.2), then the exception in the handler can be initialized directly with the argument of the throw expression. When the thrown object is a class object, and the copy constructor used to initialize the temporary copy is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated). Similarly, if the destructor for that object is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated).

like image 164
Andreas Brinck Avatar answered Oct 04 '22 11:10

Andreas Brinck


No, it's not.

15.1.5 When the thrown object is a class object, the copy/move constructor and the destructor shall be accessible, even if the copy/move operation is elided

like image 35
Tadeusz Kopec for Ukraine Avatar answered Oct 04 '22 11:10

Tadeusz Kopec for Ukraine