C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 19 May 2024 12:41:55 +0100
On Saturday, May 18, 2024, Jason McKesson wrote:

>
> In the context of an actual proposal for standard C++, there is no
> "spectrum". There is "allowed by the rules of the standard" or "not
> allowed". There may be some fuzzy lines where the language of the
> standard is unclear, but this is not one of those cases.
>
> The thing you want to do is "not allowed". Whether you can get away
> with it on some implementation is relevant only to the question of
> what it might take for future implementations to implement such
> functionality should it become "allowed by the rules of the standard"



I've been following the development of the paper to give us NRVO, and it's
become quite complicated:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2025r1.html

At least one compiler has a bug about destroying the return object when an
exception is thrown.

If that paper is just too much hassle to write into the Standard, then the
2nd best option is to use the "placement new" trick I described a post or
two ago. Yeah I know it's UB, but if it works perfectly on 27 compilers
with various CPU instruction set then I'll go with it. I haven't been able
to find a compiler that it doesn't work on.

To greatly simplify the NRVO paper, maybe we could write a much shorter
paper that allows us to do something like:

mutex Func(void)
{
    auto &m = _Retvar(mutex);
    m.lock();
    return; // returns object created by _Retvar
}

If an exception is thrown before _Retvar is invoked, then the object never
gets destroyed. However if an exception is thrown after _Retvar is invoked,
then the object does get destroyed. It would sort of behave as though you
had written:

operator _Retvar(Type, bool &to_destroy)
{
    auto &obj = ::new(_Retval_Address) Type;
    to_destroy = true;
    return obj;
}

mutex Func(void)
{
    bool destroy = false;
    try
    {
        auto &m = _Retvar(mutex, destroy);
        m.lock();
    }
    catch(...)
    {
        if ( destroy ) m.~mutex();
    }
    return;
}

I realise that this isn't very eloquent -- but if we're going to live in
the real world and accept that the NRVO paper won't get accepted because
it's just too complicated and too much hassle to write into the Standard,
then Plan B could be to do something like this. In terms of design, it
would still be slightly more beautiful than how "forwarding references"
were (mis)designed.

Received on 2024-05-19 11:42:02