On 4/10/22 20:05, norm wrote:
> On Sunday, 10 April 2022 at 23:19:47 UTC, rikki cattermole wrote:
> In my mind immutable data
> means the data will not change and neither will the result of reading
> that data, ever.
Yes.
> I don't get how you can have thread safety guarantees based on immutable
> if reading that data in a thread suddenly becomes undefined behaviour
> and could return anything.
Yes, it would be a bug to attempt to read data that is not live anymore.
> That isn't immutable then.
The lifetime of immutable data can start and end.
import std.stdio;
struct S {
int i;
this(int i) {
this.i = i;
writeln(i, " is (about to be) alive!");
}
~this() {
writeln(i, " is (already) dead.");
}
}
void main() {
foreach (i; 0 .. 3) {
immutable s = S(i);
}
}
The output:
0 is (about to be) alive!
0 is (already) dead.
1 is (about to be) alive!
1 is (already) dead.
2 is (about to be) alive!
2 is (already) dead.
Module-level immutable and 'static const' would live much longer but
they have a lifetime as well. However, today, the destructor cannot be
executed on an immutable object, so I remove the qualifiers with cast(),
which sohuld be undefined behavior (today?).
immutable(S) moduleS;
shared static this() {
moduleS = S(42);
}
shared static ~this() {
destroy(cast()moduleS);
}
void main() {
}
> Once instantiated
> immutable data persists for the remainder of the program.
That seems to be the misunderstanding. Again, I think module-level
'immutable' and 'static const' data fits that description.
> You may not
> have access if the variable goes out of scope, but if you do it will
> always be there and always return the same value when you read from
memory.
That description fits D's GC-owned data (including immutables). The
lifetime ends when there is no reference to it.
Another example is immutable messages passed between threads with
std.concurrency: That kind of data clearly originates at run time and
the receiving end keeps the data alive as long as it needs.
Ali