On 04/03/2018 05:13 PM, Steven Schveighoffer wrote:
Unfortunately, I found out that it's not just "pre-filled with some values". Member postblits are run before the containing postblit.

https://run.dlang.io/is/mt6eGa

So this means, the data that is available to the postblit has already been processed.

There's a similar situation with constructors: A constructor can call another constructor, which can lead to double initialization of fields.

Example:

----
class C
{
    int x;
    this() immutable
    {
        this(42); /* Initializes x. */
        x = 13; /* Breaking immutable, or ok? */
    }
    this(int x) immutable
    {
        this.x = x;
    }
}
----

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.

It would only make sense to allow const postblits to have the same constructor mechanism if the members all had no postblits.

Less drastically, we could also disallow writing to those fields that have their own postblit.

The analog with constructors would be disallowing writing to fields that have already been initialized by an implicit `super` call. Actually, that seems to be how it works, kinda-sorta:

----
class C
{
    int x;
}

class D : C
{
    int y;
    this() immutable
    {
        y = 1; /* accepted */
        x = 2; /* Error: cannot modify this.x in immutable function */
    }
}
----

Obviously, DMD doesn't check what C's constructor actually does (because it generally can't check that). It just considers initializing x to be C's responsibility.

Reply via email to