Making array elements truly const/immutable

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Thu Aug 2 01:55:51 PDT 2012


Hello all,

While playing around I noticed something that rather disturbed me about 
const/immutable's relationship with arrays.  If I do e.g.

     import std.stdio;

     void main()
     {
           immutable(int)[] foo = [1, 2, 3, 4, 5];

           int[] bar = cast(int[]) foo;

           bar[2] *= 2;

           foreach(b; bar)
                 writeln(b);
           writeln();

           foreach(f; foo)
                 writeln(f);
     }

... then the tweak to bar will also affect foo.

Now, it seems fairly evident why this is -- I'm taking something that is 
effectively a pointer to (immutable int) and casting it to a pointer to int, and 
so of course the latter can mutate the data contained.  I can even see potential 
applications for this kind of cast.

But, 2 questions: (i) is there a way to mark an array as "under no circumstances 
allow anything to modify the contents" in a way that _can't_ be cast away like 
this? and (ii) given that I can use instead bar = foo.dup to copy foo, is this 
guaranteed to produce a _copy_ or is it smart inasmuch as the compiler will 
check if bar is actually mutated and so only create a duplicate if needed?

The motivation is that I want to have a class which contains a dynamic array as 
a private member variable, but which is readable through a class property.  i.e. 
something like

     class Foo
     {
         private int[] _foo;
         @property immutable(int)[] foo { return _foo; }
     }

... but where it's guaranteed that no external agent can touch the inside of 
_foo.  So, yes, I could return _foo.idup, but I'd like to be able to guarantee 
that extra arrays won't be allocated unless strictly necessary.


More information about the Digitalmars-d-learn mailing list