For example:
class A {
int n;
void delegate( ) dg;
void foo() {n++;}
}
pure
A createAnA( int n ) {
A result = new A;
result.n = n;
result.dg = &result.foo;
return result;
}
void main( ) {
immutable A tmp = createAnA( 3 );
assert( tmp.n == 3 );
tmp.dg();
assert( tmp.n == 4 );
}
Because delegates cannot be cast, I think it should be illegal to cast a delegate-containing object or struct to immutable implicitly. An explicit cast should be required.
Comment #1 by lt.infiltrator — 2014-03-19T21:20:35Z
Why is this a bug? With the delegate, it is the pointer itself which becomes immutable, not the pointed-to function. This appears to be correct behaviour. Furthermore, disallowing any delegate-containing object to be immutable seems unnecessarily strict for no (?) benefit.
Comment #2 by schveiguy — 2014-03-20T12:57:35Z
It's a bug because when the object is cast implicitly to immutable, it does not affect the context pointer. In essence, the delegate captures the instance when it was mutable.
Normally, implicitly casting a pure return to immutable is OK because immutable is transitive. Since a strong pure function cannot have side effects, the return must be the only reference to it. However, if it contains a reference to itself via a delegate, that reference does NOT get cast to immutable.
Why do you think the given code is correct behavior? I should never be able to do this without casts:
immutable a = ...
assert(a.n == 3);
...
assert(a.n == 4);
BTW, I do not say that a class with delegate members should not be allowed to be immutable, I'm saying that it should not *implicitly* cast to immutable. In other words, the code would be allowed if you did:
auto tmp = cast(immutable(A))createAnA(3);
In this case, you are telling the compiler "I know what I'm doing."
Comment #3 by robert.schadek — 2024-12-13T17:56:32Z