Closed
Description
Consider a smart pointer type for IUnknown
that automatically calls IUnknown::Release
where appropriate:
ComPtr: type = {
m_raw: *IUnknown;
// ...
operator=: (inout this, move that) = {
// Take the raw pointer from `that` first.
// If `&that == &this`, setting it to nullptr
// first ensures we don't release it.
new_raw := std::exchange(that.m_raw, nullptr);
if m_raw { m_raw*.Release(); }
m_raw = new_raw;
}
// ...
}
cppfront generates the following code for the move-assignment operator:
auto ComPtr::operator=(ComPtr&& that) noexcept -> ComPtr& {
m_raw = std::move(that).m_raw;
// Take the raw pointer from `that` first.
// If `&that == &this`, setting it to nullptr
// first ensures we don't release it.
auto new_raw {std::exchange(std::move(that).m_raw, nullptr)};
if (m_raw) {CPP2_UFCS_0(Release, (*cpp2::assert_not_null(m_raw))); }
m_raw = std::move(new_raw);
return *this;
}
cppfront inserted m_raw = std::move(that).m_raw;
before my code, meaning there's no way for me to call Release()
on the old value.