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.

Reply via email to