Why do immutable variables need reference counting?

Ali Çehreli acehreli at yahoo.com
Mon Apr 11 03:24:11 UTC 2022


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



More information about the Digitalmars-d-learn mailing list