C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Wed, 22 May 2024 19:18:23 +0000
What you are describing is a completely different scenario from std::mutex, at it seams more of a semantical problem with arrays than anything else.
This problem is not new, as you very well predicted, stop using c-style arrays, if you can’t, consider perhaps passing in a pointer, if you can’t do either, then a new feature is not going to really solve your problem, the semantical ambiguities that caused this problem aren’t going away. If you can’t use a newer feature as std::array (since C++11) I have my doubts that adding an even newer feature would help.


From: Std-Proposals <std-proposals-bounces_at_[hidden]socpp.org> On Behalf Of Maciej Cencora via Std-Proposals
Sent: Wednesday, May 22, 2024 18:29
To: std-proposals_at_lists.isocpp.org
Cc: Maciej Cencora <m.cencora_at_[hidden]>
Subject: Re: [std-proposals] std::elide

Here is a real-world problem:
Let's say you need to create a serialization framework with generic API like:
template <typename T>
T deserialize();

It should support any user-defined aggregate types and with a single API the framework should support two scenarios:
1) the usual deserialize into new object on stack
auto v = deserialize<T>();
2) deserialize directly into a preallocated specific region of memory without blowing-up the stack on embedded systems for huge T
static T v;
...
new (&v) auto(deserialize<T>());

Thanks to guaranteed copy-ellision introduced in C++17 you can achieve exactly that, with exceptions of arrays.
If T is a struct containing C-style array then you cannot create deserialize specialization that uses RVO:
struct Foo { int a[1]; }
template <>
Foo deserialize()
{
    return { .a = deserialize<int[1]>() };
}

This won't compile as C-style arrays cannot be returned from function by value.

You could workaround it by expanding the array initialization with a help of std::index_sequence, like:
template <std::size_t ...Ints>
Foo deserialize(std::index_sequence<Ints...>)
{
    return { .a = { (Ints, deserialize<int>())... } };
}
But this is impossible if T has multiple arrays, or if arrays size is big (you hit template instantiations limit on your compiler, and what is worse the compilers don't fold this back into a loop so your binary gets huge).

You may say don't use C-style arrays, but the decision may not be up to you.
And even if you force std::array you get hit by the template instantiations limit and binary bloat anyway.

With NRVO you could have it all.

Regards,
Maciej Cencora





śr., 22 maj 2024 o 17:00 Tiago Freire via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> napisał(a):
As mentioned before, it is not enough to have a theoretical discussion, you need a practical reason to justify adding a new feature.
You have to consider alternative ways to do what you are trying to do, and then justify why your approach is better.
And what has been displayed was a convoluted amount of code to try and write something that shouldn't been written, and whose alternative is a single line of code.

The argument is not convincing, and you need to convince me that other objects that are also not movable don't have the exact same issues, justifying why you need to enforce RVO instead of passing in a reference.
Get an example that actually needs it, then we have a point of discussion, until then it is not solving a problem.
I hope I made my point clear.


-----Original Message-----
From: Std-Proposals <std-proposals-bounces_at_[hidden].org<mailto:std-proposals-bounces_at_[hidden]>> On Behalf Of Frederick Virchanza Gotham via Std-Proposals
Sent: Wednesday, May 22, 2024 16:37
To: std-proposals_at_lists.isocpp.org<mailto:std-proposals_at_[hidden]>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]<mailto:cauldwell.thomas_at_[hidden]>>
Subject: Re: [std-proposals] std::elide

On Wed, May 22, 2024 at 2:17 PM Tiago Freire wrote:
>
> While I can understand RVO, mutexes has got to be the worst possible
> example for an application of this.


Let's say it's Summer time and I'm out the back garden at my house on a sunny day, and I'm trying out my brand new fruit blender. Tiago, you come over to my house and I've already made my smoothie, but there's still one pineapple sitting on the table, and even though a pineapple isn't a great choice of fruit for blending, it's right there right now and so I just grab it and throw it in the blender to show off my new blending skills. I could have stood up and walked into my house to the kitchen to grab a softer piece of fruit but I'm just not bothered -- the pineapple is there and it will do.

We've been consistently using "std::mutex" because it's right there right now. We just need to write "#include<mutex>" and we have an unmovable-and-uncopyable type. That's literally the only reason we're all talking about mutexes in this thread. It's easier to write those
15 characters, "#include<mutex>", than to go to the bother of typing
out:

    struct S {
        MyClass(MyClass const &) = delete;
        MyClass(MyClass &&) = delete;
        int n;
    };

You seem to be very technically-minded Tiago and perhaps that's why you drill further into the logic than the rest of us here. Sometimes though, we just want a quick-and-easy example to demonstrate an idea we're working on -- and sometimes we don't give much consideration to how sensible our quick-and-easy example is. The world would probably be a better place if we were all as analytically-prone as you Tiago, but for the time being we just want to write out short little simple code snippets.
--
Std-Proposals mailing list
Std-Proposals_at_lists.isocpp.org<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals_at_lists.isocpp.org<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-05-22 19:18:26