Date: Fri, 7 Apr 2023 20:50:42 +0200
On 07/04/2023 19.14, Jan Schultke via Std-Proposals wrote:
> For many operator overloads like assignment or pre-increment, as well
> as builder pattern functions, you tend to write:
> return *this;
>
> What if we could write the following:
> struct T {
> int i;
> this operator++() { ++i; }
> };
>
> A return type of `this` would result in an implicit return T by
> reference, with qualifiers taken from the function (e.g.
> const-qualified member functions return const T&). This saves one line
> of boilerplate in many places, saves developers from forgetting to
> return *this, and can improve performance.
I can see this is technically feasible, but it adds a little more
special-casing to the language without significantly increasing
the expressiveness (but see below). At this point, I'm not convinced
the effort-vs.-reward ratio is good enough. A potential future
paper should discuss these concerns:
Compilers are pretty good giving a warning when you fall off the end of
a value-returning function.
"this" has pointer type, but the syntax actually wants to describe
by-reference return (i.e. "return *this"). There is a disconnect
in the syntax here.
> Namely it improves performance because it can help with devirtualization:
> x.fun1().fun2().fun3()
>
> If three virtual member functions return T&, that T& may not be a
> self-reference, so it requires a vtable lookup each time. If the
> member functions return "this", then the dynamic type must stay the
> same and the second and third call can use the same vtable pointer.
I can see that argument (note the redundant vtable loads):
https://www.godbolt.org/z/9516f5PY3
However, using "this return" in this case would introduce
covariant return types, which come with their own thunk
mechanism for pointer adjustments, which may or may not be
desirable.
Also, I note that the "operator++" use case is one where virtual
functions are discouraged in the code bases I've seen.
Do you have a sample implementation that can demonstrate
actual performance improvements for the generated code?
I wouldn't expect virtual functions to be used pervasively
in hot code paths.
Jens
> For many operator overloads like assignment or pre-increment, as well
> as builder pattern functions, you tend to write:
> return *this;
>
> What if we could write the following:
> struct T {
> int i;
> this operator++() { ++i; }
> };
>
> A return type of `this` would result in an implicit return T by
> reference, with qualifiers taken from the function (e.g.
> const-qualified member functions return const T&). This saves one line
> of boilerplate in many places, saves developers from forgetting to
> return *this, and can improve performance.
I can see this is technically feasible, but it adds a little more
special-casing to the language without significantly increasing
the expressiveness (but see below). At this point, I'm not convinced
the effort-vs.-reward ratio is good enough. A potential future
paper should discuss these concerns:
Compilers are pretty good giving a warning when you fall off the end of
a value-returning function.
"this" has pointer type, but the syntax actually wants to describe
by-reference return (i.e. "return *this"). There is a disconnect
in the syntax here.
> Namely it improves performance because it can help with devirtualization:
> x.fun1().fun2().fun3()
>
> If three virtual member functions return T&, that T& may not be a
> self-reference, so it requires a vtable lookup each time. If the
> member functions return "this", then the dynamic type must stay the
> same and the second and third call can use the same vtable pointer.
I can see that argument (note the redundant vtable loads):
https://www.godbolt.org/z/9516f5PY3
However, using "this return" in this case would introduce
covariant return types, which come with their own thunk
mechanism for pointer adjustments, which may or may not be
desirable.
Also, I note that the "operator++" use case is one where virtual
functions are discouraged in the code bases I've seen.
Do you have a sample implementation that can demonstrate
actual performance improvements for the generated code?
I wouldn't expect virtual functions to be used pervasively
in hot code paths.
Jens
Received on 2023-04-07 18:50:47