C++ Logo

std-proposals

Advanced search

Re: [std-proposals] this return type

From: Jan Schultke <janschultke_at_[hidden]>
Date: Fri, 7 Apr 2023 23:18:29 +0200
> I find this argument for improved performance bogus.

You're right to an extent, the benefit is not that it saves vtable
lookups. At least this doesn't happen in practice, because the vtable
pointer usually lives in caller-preserved registers, and every virtual
call may overwrite those. So even if we know that the vtable pointer
stayed the same, we lost it due to calling conventions and need to
touch memory again.

The main benefit is that for a devirtualized type, returning T& makes
the next call virtual again, because we go back to the virtualized
base type. With a this return type, we guarantee that the object stays
the same, so the call chain remains devirtualized. Also see my
response to Jens Maurer.

> If you have a virtual function that has the signature `virtual Base&
> fun1()` then how do you ensure that an implementation of that function
> must return a self-reference?

By having a "this" return type which guarantees that not only the type
is the same, but the returned reference is same as the called-upon
reference. I also don't see a problem with making this part of the
interface. It makes sense to differentiate between functions that can
return references to other objects, and functions which are merely
intended for chaining.

> An alternative approach is that Base has a private `virtual void
> do_fun1()` member function and a public inline `Base& fun1() {
> do_fun1(); return *this; }` member function. This should achieve the
> same performance as the proposed this return type.

Yes, this is true, this should keep the call chain de-virtualized.
However, I find it very hard to justify writing this in practice.


>


On Fri, Apr 7, 2023 at 10:04 PM Lénárd Szolnoki via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On Fri, 2023-04-07 at 19:14 +0200, 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.
> >
> > 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 find this argument for improved performance bogus.
>
> If you have a virtual function that has the signature `virtual Base&
> fun1()` then how do you ensure that an implementation of that function
> must return a self-reference?
>
> If the intent is that a derived class shouldn't be able to alter self-
> reference returning behaviour of Base::fun1, then `virtual Base&
> fun1()` is the wrong customisation point in the interface.
>
> An alternative approach is that Base has a private `virtual void
> do_fun1()` member function and a public inline `Base& fun1() {
> do_fun1(); return *this; }` member function. This should achieve the
> same performance as the proposed this return type.
>
> Granted, this is even more boilerplate than what needs to be done for
> non-virtual member functions, so the proposal still has an edge on the
> "reducing boilerplate" area. I just think that the original example for
> the performance benefit is not apples to apples.
>
> Cheers,
> Lénárd
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-04-07 21:18:41