Deprecating this(this)

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Apr 5 19:09:07 UTC 2018


On Thursday, April 05, 2018 11:46:25 H. S. Teoh via Digitalmars-d wrote:
> On Wed, Apr 04, 2018 at 05:08:26PM -0600, Jonathan M Davis via
> Digitalmars-d wrote: [...]
> > Hmmm. And actually, thinking about that, I almost wonder if we could
> > just change this(this) to be a copy constructor. Assume for a moment
> > that inside this(this), we provide a new symbol that is the this
> > pointer/reference for the original. We then have make it so that any
> > member variable in the newly constructed object which is read before
> > it is assigned is default-copied. As such,
> >
> > this(this)
> > {
> > }
> >
> > would just default-copy everything basically as it does now.
>
> Why even bother with declaring an empty this(this)?  Just leave it out,
> and the compiler assumes default-copy.

You wouldn't declare it. I was just talking about it to discuss the
semantics.

> > However, if we provide the object being copied via an invisible ref
> > (like this) called orig, doing
> >
> > this(this)
> > {
> >
> >     _foo = orig._foo;
> >
> > }
> >
> > then that would directly initialize _foo without it being
> > default-copied. As such, existing postblit constructors should
> > continue to work, but it would be straightforward to turn them into
> > copy constructors, and most of the changes would be underneath the
> > hood.
>
> [...]
>
> I like this idea.  Except the syntax could be improved:
>
>   this(this orig)     // <-- N.B.
>   {
>       _foo = orig._foo;
>   }
>
> Let the user specify the symbol, instead of introducing yet another
> implicit magic identifier. :-)

Well, that might be better in that it allows the user to choose the name,
but it then opens up the question of whether this(this) should be
deprecated, and part of the point was to try and just do it all in-place and
simply turn postblit constructors into copy constructors - though it could
be argued that this(this) was just a copy constructor where you didn't
bother to use the original, and anyone actually wanting to take advantage of
copy constructors is going to need to make changes anyway. But if this(this)
simply becomes a copy constructor (whether a default name is used or
something like this(this orig) is used to define the name), then we
hopefully would be able to avoid actually deprecating anything and just make
more code work and making it so that only minor tweaks are necessary to
actually take full advantage of it being a copy constructor instead of
mutating the copy in the copy constructor.

The other issue that occurred to me after posting about this was the
question of what to do about const. Ideally, this(this) or this(this orig)
would work just fine with const (assuming that it didn't do anything that
would mutate the object), but someone might want to actually require const
or overload the copy constructor for the const case, in which case, I was
thinking making this(const this), but with your suggestion, I guess that it
would become either this(const this orig) or this(this const orig). I don't
know. As usual, adding const into the mix makes things messier, but part of
the point of all of this is to make it so that we can copy arbitrarily
complex const objects.

In any case, I think that the idea of trying to simply turn postblit
constructors into copy constructors has merit. I certainly don't think that
we need to be doing anything like

struct S
{
    this(ref S orig)
    {
        ...
    }
}

where everyone will have to convert their postblits over time in order to
avoid the deprecation and where it actually risks conflicting with existing
constructors.

- Jonathan M Davis



More information about the Digitalmars-d mailing list