Deprecating this(this)

ag0aep6g anonymous at example.com
Tue Apr 3 21:44:02 UTC 2018


On 04/03/2018 10:51 PM, Steven Schveighoffer wrote:
> On 4/3/18 4:26 PM, ag0aep6g wrote:
[...]
>> If there's a problem with running two postblits on the same field, 
>> then I think constructors probably have similar issue. I'm having a 
>> hard time finding a good example, though. One where we could break 
>> immutable in an obvious way or some such.
> 
> You may NOT want to run a postblit on the member. If all you are going 
> to do, for example, is reassign a variable, then running the postblit, 
> and then the destructor, just so you can overwrite it is pointless.

Same with class constructors: You may not want to run `super` when 
you're just going to overwrite what it did. But the language doesn't 
give you a choice. It'll be called one way or another.

I'm not saying that imitating how constructors work will make the best 
possible copying mechanism. Something else might be superior in every 
way. It's just that so far the arguments against a constructor-like 
postblit also seem to apply to constructors as they are implemented.

So I'm thinking that a postblit modeled after constructors could work as 
well as they do. But maybe the real takeaway is that constructors don't 
work very well, and shouldn't be imitated.

> But more importantly, if the postblit of the member does something crazy 
> like stores a reference to itself as an immutable elsewhere, and then 
> the compiler allows overwriting, we now have problems.

I'd love to see an example of this in code. The best I can come up with 
would be something like this (doesn't compile):

----
import std.stdio;

immutable(int)* p;

struct S
{
     int x;
     this(this) immutable
     {
         x = 42; /* First write. */
         .p = &this.x;
         writeln(p, " ", *p); /* Prints some address and 42. */
     }
}

struct T
{
     S s;
     this(this) immutable
     {
         s = S(13); /* Second write. Breaking immutable? */
         writeln(p, " ", *p); /* Same address, but 13. */
     }
}

void main()
{
     immutable T foo;
     immutable bar = foo;
}
----

But that's essentially the same as the class example I posted. `*p` 
would only change values during the postblit run. Just like a 
constructor chain can write to the same field multiple times.

That's kinda iffy, but I can't find a way to demonstrate some real, 
obvious damage.

> I think the better mechanism for immutable copying would be to have a 
> copy constructor that starts off with T.init, and is passed the object 
> to copy from. That seems to be a direction Andrei is considering.

No objection from me. If Andrei et al. can find a better solution, great.


More information about the Digitalmars-d mailing list