On Monday, 19 November 2018 at 14:04:29 UTC, Dennis wrote:
On Monday, 19 November 2018 at 13:34:50 UTC, Stanislav Blinov
wrote:
Because it's not mutation, it's initialization.
Ohhhhh. That's an epiphany for me.
:)
When a ctor is `pure`, the compiler knows it doesn't mutate
any state other than the object's, so it allows conversion to
all three qualifiers.
I had trouble thinking of an example where impure constructors
would break immutable, but now I get it:
```
int* gPtr;
struct S {
int a;
this(int a) {
this.a = a;
gPtr = &this.a;
}
}
void main() {
S s = 1;
(*gPtr)++;
}
```
s can't be immutable because its field could be mutated, so the
constructor needs to be pure (so gPtr can't be set) or
immutable (so &this.a is an immutable(int)*).
Yep. Or the other way around (as I said earlier, it really makes
sense when you have indirections inside the struct):
int* global;
struct S {
const(int)* a;
this(bool b) {
if (b) a = global;
else a = new int;
}
}
You obviously can't instantiate an immutable S with that ctor,
since const(int)* may point to mutable data. Nor can you make
that ctor `pure`. However this is fine:
immutable(int*) global; // note it's an immutable(int*), not an
immutable(int)*
struct S {
const(int)* a;
this(bool b) pure {
if (b) a = global;
else a = new int;
}
}