C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Replace an object -- but retain old object if new object fails to construct

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Tue, 21 Oct 2025 18:43:14 +0100
On Tue, 21 Oct 2025 at 18:39, Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> How about for that use case one creates a
>
> double_optional<std::mutex>
>
> switching between both buffers inside the double_optional (no heap
> allocation).
>

Or just use the heap.


> Normally only one of the buffers has a valid object, except for the short
> time, the try_emplace (or how it was named) is called. Then during the
> constructor and destructor both objects exist.
>
>
>
> Disadvantages:
>
> - needs double the memory size
>
> - address of the actual std::mutex can change depending on which buffer
> is active
>
>
>
> Advantages:
>
> - no copying / moving / relocating necessary
> * compatible with more objects
>
> * better performance
>
> - possible with current C++
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Di 21.10.2025 19:09
> *Betreff:* Re: [std-proposals] Replace an object -- but retain old object
> if new object fails to construct
> *Anlage:* signature.asc
> *An:* std-proposals_at_[hidden];
> *CC:* Thiago Macieira <thiago_at_[hidden]>;
> On Tuesday, 21 October 2025 09:03:28 Pacific Daylight Time Frederick
> Virchanza
> Gotham via Std-Proposals wrote:
> > (Step 1) Copy the bytes of the current object into a temporary buffer
> > on the stack
> > (Step 2) Construct the new object at the original location of the old
> > object (i.e. overwrite the old object)
> > (Step 3) If constructor throws an exception, move the old object's
> > bytes back from the temporary buffer (i.e. restore the old object)
> > (Step 4) Otherwise, if construction succeeds, swap the two buffers,
> > call the destructor to destroy the old object, then swap the two
> > buffers again
>
> What if the constructor in step 2 attempts to use the object that was
> there?
> It's perfectly possible for constructors to access a global list of live
> objects. Likewise for the destruction in step 4 could access the list of
> live
> objects.
>
> This cannot be done in the generic case. I suggest this feature require
> that
> the class type be relocatable, otherwise it shouldn't be available.
>
> > Now see here's the thing . . . I'm probably more of a firmware
> > engineer than a software engineer, and so I have a little difficulty
> > maintaining respect for the "object model" since I deal so much with
> > copper and voltages and CPU registers, but I can at least concede that
> > my above code absolutely decimates the object model in the most
> > horrendous and unspeakable manner. Also I'm pretty sure I'm not
> > allowed to 'memcpy' a class like 'std::mutex' either.
>
> Only memcpying it away and back again is fine, because under the as-if
> rule one
> can't tell you did that. The problem is that you did something to its
> storage
> space while the object was away and that violates as-if.
>
> And a likely type to know of existing objects are mutexes, because for
> almost
> every OS out there they must make a system call to initialise OS-specific
> objects. If you doubt me, look at FreeBSD's implementation of
> pthread_mutex:
> https://github.com/freebsd/wireless/blob/main/lib/libthr/thread/thr_mutex.c
>
> https://github.com/freebsd/wireless/blob/main/lib/libthr/thread/thr_private.h
> It even has a linked list!
>
> [Fortunately, on the majority of OSes, there's a way to constexprly
> initialise
> a std::mutex object, delaying the full initialisation to the first lock()
> call.
> libc++ appears to require that mode, but libstdc++ supports non-constexpr
> inits and *uses* that for Windows, calling InitializeCriticalSection()].
>
> > So anyway, to get around the whole object model boggle and memcpy's
> > class bytes, perhaps could the standard library be given a new
> > function called something like "emplace_or_retain", and so then
> > compiler vendors could take my above code and put it in their header
> > files and then put some fine print with it saying "The compiler
> > maintains the sanctity of the C++ object model when compiling this
> > code".
>
> As I said above, I think only for relocatable objects. Which std::mutex
> won't
> be.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel Data Center Group
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-10-21 17:43:34