Artur Pyszczuk
Artur Pyszczuk

Reputation: 1930

Exception in move assignment operator

Consider:

struct Boo {
    Boo (std::string v) : src {v} {}

    Boo (const Boo&) = delete;
    Boo& operator= (const Boo&) = delete;

    Boo (Boo&& b) : src {std::move (b.src)} {}

    Boo& operator= (Boo&& b) {
        if (this != &b) {
            foo ();
            src = std::move (b.src);
        }
        return *this;
    }

    void show () {
        std::cout << "|" << src << "|" << std::endl;
    }

    void foo () {
        throw 1;
    }

    std::string src {};
};

and usage:

int main(int argc, char** argv) {

    Boo s {"Boo1"};
    Boo p {"Boo2"};

    try {
        p = std::move (s); // (X)
    }
    catch (...) {}

    s.show ();
    p.show ();

    return 0;
}

And outputs look like this:

If foo() is invoked in move assignment operator

|Boo1|
|Boo2|

If foo() is not invoked

|Boo2|
|Boo1|

Questions:

What happens with s when exception is thrown in move assignment operator? Does it have previous content just like before using std::move() in line (X), or the content is completely moved to the b (function parameter)?

Why in both cases outputs show that content is still in std::string objects?

Upvotes: 2

Views: 474

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409176

When an exception is thrown, normal execution halts immediately, and the call stack is unwound. until the first valid catch. For your case it means that as soon as you throw the continued execution of the foo and the assignment operator functions are halted and the program goes to the catch in the main function, in other words nothing happens that would alter the objects.

Moving a std::string object leaves the source in a valid but uspecified state. It should be noted that moving is commonly implemented by swapping source and destination, which will explain the behavior you see.

Upvotes: 3

Related Questions