C++ Logo

std-proposals

Advanced search

[std-proposals] Allow std::optional to give pointer to yet-to-be-constructed

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Tue, 13 Dec 2022 12:47:41 +0000
I'm currently writing a program on an x86_64 desktop computer which
will run on MS-Windows, so there are places in my C++ code where I can
write undefined behaviour because I know how this particular
implementation works (i.e. I'm familiar with the compiler + CPU +
memory layout + operating system).

Just yesterday I wanted to do two things:
(1) Show a dialog box
(2) Start a new thread

My debacle however was as follows:
    a) The constructor for the DialogBox needs the stop_token of the thread
    b) The entry point for the thread needs the address of the DialogBox

So if I created the DialogBox first then I wouldn't have the
stop_token, and if I created the thread first then I wouldn't have the
DialogBox. It's a chicken and egg problem.

So here's what I did:

    std::optional<Dialog_Waiting> dlg;

    this->worker_thread = std::jthread(
        Thread_Entry_Point,
        static_cast<Dialog_Waiting*>(static_cast<void*>(&dlg)) ); //
yeah yeah I know I know

    dlg.emplace( this, this->worker_thread.get_stop_source() );

And then just to be doubly-sure, I wrote this after it:

    if ( static_cast<Dialog_Waiting*>(static_cast<void*>(&dlg)) !=
&dlg.value() )
    {
        MsgBox("The programmer needs to edit the contents of the function, "
               "Dialog_Main::OnClick_SendCommands because the std::optional "
               "object has the wrong address.");

        return;
    }

Would it not be better to give std::optional an extra member function
to get the address of 'where the object would be constructed',
something like:

template<typename T>
class optional {
    alignas(T) char unsigned buf[sizeof(T)];

public:
    T * GetAddress(void) const
    {
        return static_cast<T*>(static_cast<void*>(buf + 0u));
    }
};

If we were to add this feature to C++26, then we could simply give the
following caveat in:
    "Behaviour is undefined if you dereference the return value
     from std::optional<T>::GetAddress when *this does not contain
     a value."

Received on 2022-12-13 12:47:53