Open
Description
reproc/reproc++/include/reproc++/detail/array.hpp
Lines 23 to 30 in 08675b1
The move-assignment operator is not actually moving but copying.
#include <iostream>
struct S {
S(char *s) : s_(s) {}
S(S&& rhs) : s_(rhs.s_) { rhs.s_ = nullptr; }
S& operator=(S&& rhs) { s_ = rhs.s_; return *this; }
~S() { *s_ = 0; s_ = nullptr; }
char *s_;
};
int main() {
char word1[] = { "hello" };
char word2[] = { "hello" };
S s1(word1);
std::cout << "s1.s_ = '" << s1.s_ << "'\n";
s1 = std::move(S(word2));
std::cout << "s1.s_ = '" << s1.s_ << "'\n";
}
https://gcc.godbolt.org/z/az44M1577
Program stdout
s1.s_ = 'hello'
s1.s_ = ''
Move should be implemented as swap or exchange:
S(S&& rhs) :
s_(std::exchange(rhs.s_, nullptr))
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//
{}
S& operator=(S&& rhs) {
std::swap(s_, rhs.s_);
//^^^^^^^^^^^^^^^^^^//
return *this;
}
https://gcc.godbolt.org/z/5fzrhaGvd
array(array &&other) noexcept
// if other == this, somehow, we'll take data_, replace it with nullptr,
// and then replace that with the save of data_, etc.
: data_(std::exchange(other.data_, nullptr))
, owned_(std::exchange(other.owned_, false))
{
}
array &operator=(array &&other) noexcept
{
// transfer whatever we owned previously to the rvalue, so it can clean
// up any data we previously had.
// {
// array one(...);
// array two(...);
// ...
// two = std::move(one); // two's data transferred to one, which the
// // compiler may now destruct here or later.
// ...
// one = array(...); // what two allocated is moved to the temporary,
// // and then destructed here in rvalue::~array()
// ...
// } // << whatever is still in two destructed here
// this also eliminates the need for the potentially branch-inducing self check.
std::swap(data_, other.data_);
std::swap(owned_, other.owned_);
return *this;
}
Metadata
Metadata
Assignees
Labels
No labels