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.