Can I safely move assign to `this`?
Asked Answered
T

1

15

I was wondering if it's safe to write a reset method of some class A by using the move assignment operator on this.

So instead of

A a{};
... // Do something with a
a = A();

if I could write

A a{};
... // Do something with a
a.reset();

where

void A::reset()
{
  *this = A();
}

I played arround a bit on godbolt (https://godbolt.org/z/Edc3TT1aT ) and the resulting debug assembly is almost identical with gdb for this example.

Triumvirate answered 10/6, 2022 at 13:51 Comment(7)
Yes, that's safe. (Modulo any bugs in the class's operator=, and the class having proper ownership management of resources in its member variables.)Declaratory
Would *this = std::move(A()); be safer? Or is that unnecessary? I'm thinking about possible side-effects of the source (local) A being destroyed when it goes out of scope; but maybe I'm just confused.Forthright
@AdrianMole *this = std::move(A()); and *this = A(); does the same thingEckhart
@AdrianMole: *this = A(); is already a prvalue, std::move would not improve things at all (there are some cases where it makes things worse, e.g. in function return values where the use of std::move inhibits copy-elision and causes an unnecessary move and destruction, while returning it directly invokes no constructors at all).Shelleyshellfire
Thanks, all. It's Friday (but not yet Beer O'clock) and I'm already confused. :-)Forthright
@AdrianMole: Short version: You use std::move from named objects (strictly speaking, lvalues, to convert them to xvalues [a type of rvalues]) or things attached to named objects (e.g. indexing or attributes). There are exceptions (with compilers supporting NRVO, you want to avoid it for function return values), but in general, if you're assigning from an object with a name in the current scope (not something returned by a function call, not something constructed directly in the expression), std::move can help, but if there is no "thing" to move from, it's pointless at best.Shelleyshellfire
@Shelleyshellfire where NRVO could apply i.e. when returning automatic variable, std::move would also be redundant because in that specific case, move constructor will be used regardless (if not elided by NRVO).Klepht
K
5

In general, assigning to *this is not wrong. Neither copy nor move.

Whether it's correct depends on what your move assignment operator does, and what you need the reset function to do. If the assignment does the right thing, then it's correct.

Klepht answered 10/6, 2022 at 13:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.