Date: Mon, 20 May 2024 09:24:55 -0400
On Mon, May 20, 2024, 8:34 AM Lénárd Szolnoki via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
>
> On 19/05/2024 21:28, Frederick Virchanza Gotham via Std-Proposals wrote:
> > On Sunday, May 19, 2024, Jason McKesson wrote:
> >>
> >> Then you haven't actually fixed the problem, have you? If you believe
> >> that the standard needs a way to do NRVO, then providing a "way to do
> >> NRVO" that doesn't represent legal C++ code is not actually fixing the
> >> problem.
> >
> >
> > Well you can make it all legal C++ code if you tinker with the object
> > files instead of the C++ source files. For example I can write the
> > following function:
> >
> > void Func(void *const p)
> > {
> > auto &m = *::new(p) mutex{};
> > try
> > {
> > m.lock();
> > }
> > catch(...)
> > {
> > m.~mutex();
> > throw;
> > }
> > }
> >
> > And compile it to an object file which will export the following
> > symbol: _Z4FuncPv
> >
> > Then all you need to do is use 'objcopy' (or a hex editor) to rename
> > that symbol to: _Z4Funcv
> >
> > And now it behaves as though you had written:
> >
> > mutex Func(void)
> > {
> > mutex m;
> > m.lock();
> > return m;
> > }
> >
> > And then in a separate translation unit, you declare the function as:
> > extern mutex Func(void);
> > Or . . . to make things even simpler, just define the function as
> > "extern C" and then you don't have to change the linker symbol as it
> > will simply be "Func".
> >
> > As fun and interesting as this back-and-forth is, Jason, let's get to
> > the crux of the matter. There's already a lengthy paper to provide
> > NRVO:
> >
> >
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2025r2.html
> >
> > This paper has been gathering dust for 3 years (actually a few more
> > than that if you consider the previous revisions), and it's not
> > because it's a bad paper. I think it hasn't had any thrust behind it
> > because it's just too much grief to write it into the Standard and for
> > compiler vendors to implement it. So if P2025 is going to gather dust
> > past C++26, C++29, C++32 and so on, then how about we just try
> > something less ambitious.
>
> I think it's a great paper, and I think it's gathering dust for much
> more banal reasons, like the original author not having the time or
> motivation to update it, somebody else to have the motivation to pick it
> up.
>
I would have been interested in picking it up, but I looked at the minutes
and the reflector discussion and it seemed like there were significant
implementability challenges that are difficult for me to even understand.
Do we even know whether the proposed direction was actually viable?
> I personally think it's a great paper, but one of the short-coming is
> that it should require an opt-in syntax for NRVO, and that invites the
> inevitable bikeshedding around syntax that can destroy any remaining
> motivation from paper authors.
>
> > A less-ambitious alternative would be to
> > allow something like:
> >
> > mutex Func(void)
> > {
> > auto &m = _Retvar{};
> > m.lock();
> > return _Retvar;
> > }
> >
> > I propose that the operator "_Retvar" can only be used in a function
> > that returns by value. Its job is to create an object of the return
> > type, and it returns a reference to the new object. Then later you
> > just write "return _Retvar" to return from the function.
>
> I think if you are going to propose a barebones solution with many
> undefined behavior traps, than what should be done is to just expose the
> return slot to the function body as storage, without automatically
> constructing anything there. Then it's the responsibility of the
> function to populate the return slot, if the function exits by exception
> or to ensure that the return slot is empty, if it exits by exception.
>
> I'm not a huge fan of this, because it's easy to misuse compared P2025,
> which is already very flexible, but arguably this is simpler to implement.
>
> Anyway, some food for thought: functions can and do reuse the return
> slot multiple times, P2025 also allows this:
>
> Widget foo(string some_arg) {
> {
> Widget widget(some_arg); // widget is created on return slot
> if (widget.check_something()) {
> return widget; // return normally...
> }
> } //... or destroy widget
> return Widget("default"); // and return an entirely different object
> }
>
> IME clang optimizes this to use NRVO for `widget`, gcc does not.
>
> So the return slot's occupancy can be on and off throughout the
> execution of the function.
>
> Cheers,
> Lénárd
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
std-proposals_at_[hidden]> wrote:
>
>
>
> On 19/05/2024 21:28, Frederick Virchanza Gotham via Std-Proposals wrote:
> > On Sunday, May 19, 2024, Jason McKesson wrote:
> >>
> >> Then you haven't actually fixed the problem, have you? If you believe
> >> that the standard needs a way to do NRVO, then providing a "way to do
> >> NRVO" that doesn't represent legal C++ code is not actually fixing the
> >> problem.
> >
> >
> > Well you can make it all legal C++ code if you tinker with the object
> > files instead of the C++ source files. For example I can write the
> > following function:
> >
> > void Func(void *const p)
> > {
> > auto &m = *::new(p) mutex{};
> > try
> > {
> > m.lock();
> > }
> > catch(...)
> > {
> > m.~mutex();
> > throw;
> > }
> > }
> >
> > And compile it to an object file which will export the following
> > symbol: _Z4FuncPv
> >
> > Then all you need to do is use 'objcopy' (or a hex editor) to rename
> > that symbol to: _Z4Funcv
> >
> > And now it behaves as though you had written:
> >
> > mutex Func(void)
> > {
> > mutex m;
> > m.lock();
> > return m;
> > }
> >
> > And then in a separate translation unit, you declare the function as:
> > extern mutex Func(void);
> > Or . . . to make things even simpler, just define the function as
> > "extern C" and then you don't have to change the linker symbol as it
> > will simply be "Func".
> >
> > As fun and interesting as this back-and-forth is, Jason, let's get to
> > the crux of the matter. There's already a lengthy paper to provide
> > NRVO:
> >
> >
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2025r2.html
> >
> > This paper has been gathering dust for 3 years (actually a few more
> > than that if you consider the previous revisions), and it's not
> > because it's a bad paper. I think it hasn't had any thrust behind it
> > because it's just too much grief to write it into the Standard and for
> > compiler vendors to implement it. So if P2025 is going to gather dust
> > past C++26, C++29, C++32 and so on, then how about we just try
> > something less ambitious.
>
> I think it's a great paper, and I think it's gathering dust for much
> more banal reasons, like the original author not having the time or
> motivation to update it, somebody else to have the motivation to pick it
> up.
>
I would have been interested in picking it up, but I looked at the minutes
and the reflector discussion and it seemed like there were significant
implementability challenges that are difficult for me to even understand.
Do we even know whether the proposed direction was actually viable?
> I personally think it's a great paper, but one of the short-coming is
> that it should require an opt-in syntax for NRVO, and that invites the
> inevitable bikeshedding around syntax that can destroy any remaining
> motivation from paper authors.
>
> > A less-ambitious alternative would be to
> > allow something like:
> >
> > mutex Func(void)
> > {
> > auto &m = _Retvar{};
> > m.lock();
> > return _Retvar;
> > }
> >
> > I propose that the operator "_Retvar" can only be used in a function
> > that returns by value. Its job is to create an object of the return
> > type, and it returns a reference to the new object. Then later you
> > just write "return _Retvar" to return from the function.
>
> I think if you are going to propose a barebones solution with many
> undefined behavior traps, than what should be done is to just expose the
> return slot to the function body as storage, without automatically
> constructing anything there. Then it's the responsibility of the
> function to populate the return slot, if the function exits by exception
> or to ensure that the return slot is empty, if it exits by exception.
>
> I'm not a huge fan of this, because it's easy to misuse compared P2025,
> which is already very flexible, but arguably this is simpler to implement.
>
> Anyway, some food for thought: functions can and do reuse the return
> slot multiple times, P2025 also allows this:
>
> Widget foo(string some_arg) {
> {
> Widget widget(some_arg); // widget is created on return slot
> if (widget.check_something()) {
> return widget; // return normally...
> }
> } //... or destroy widget
> return Widget("default"); // and return an entirely different object
> }
>
> IME clang optimizes this to use NRVO for `widget`, gcc does not.
>
> So the return slot's occupancy can be on and off throughout the
> execution of the function.
>
> Cheers,
> Lénárd
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2024-05-20 13:25:10