C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Way to get rid of valueless_by_exception in std::variant

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Tue, 28 Oct 2025 14:01:33 +0000
On Tue, 28 Oct 2025, 12:48 Nikl Kelbon, <kelbonage_at_[hidden]> wrote:

> > Again, this is potentially undefined behaviour.
>
> Thats why it must be in standard library, others cannot do it without UB
>
> About memcpy, it seems for you, that its not correct, because you're used
> to the fact that it's wrong. But if you memswap ANY type twice into buffer
> and into original place again any type, even self reference, will work.
>

The standard is clear. If you do that for a type which is not trivially
copyable, it's undefined.



> Its impossible to break something with such memory manipulations
>

Wanna bet?

Consider:

std::variant<A,B> v1{A{}};
std::variant<A,B> v2{B{}};
try {
  v1 = std::move(v2);
} catch (...) {
  // Assume v1 cannot be valueless
  std::get<A>(v1).fun();
}

and a global:

std::map<void*, std::type_info> objects;

where B::B(B&&) does:

B::B(B&& b)
try {
  objects[this] = typeid(B);
} catch (...) {
  objects.erase(this);
}

And:

void A::fun()
{
  assert(objects[this] == typeid(A));
}

The move ctor of B throws, so if you had memcpy'd the A aside and then
swapped it back again, objects would not contain any element for the
address of that object. When you call A::fun() it finds the object is not
"live".

This is just a demonstration of one way that non-trivially copyable objects
can break if you memcpy them out and back again. It's not impossible.

Received on 2025-10-28 14:01:50