C++ Logo

std-proposals

Advanced search

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

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Tue, 13 Dec 2022 13:59:08 +0000
On 13 December 2022 12:52:26 GMT, Ville Voutilainen via Std-Proposals <std-proposals_at_[hidden]> wrote:
>On Tue, 13 Dec 2022 at 14:47, Frederick Virchanza Gotham via
>Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> 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."
>
>std::optional already has this feature, just call opt.operator->() and
>it'll give you what you suggest to be added
>here.

That's library UB.

https://timsong-cpp.github.io/cppwp/n4868/optional.observe#1

Cheers,
Lénárd

Received on 2022-12-13 13:59:15