constness for arrays

xs0 xs0 at xs0.com
Tue Jul 18 04:00:05 PDT 2006


As has been discussed, the lack of something like C++ const hurts most 
when using arrays, as you can't code around it like with classes, 
structs or primitives (with the latter two you can just pass by value, 
for classes you can make readonly versions). The fact that inbuilt 
strings are also arrays makes the problem occur often.

I was wondering whether the following would resolve that issue:

- the top bit of arrays' .length becomes an indicator of the 
readonlyness of the array reference

- type of .length is changed from uint to int (just to indicate the 
proper maximum value; it still can't be negative (from the user's POV))

- arrays get a .isReadonly property which tests the top bit

- arrays get a .lock() method that sets it to 1

- .dup clears it (obviously :)

- reading .length masks the bit out

- setting .length sets the bit to zero if reallocation occurs, and 
leaves it intact otherwise

- arrays get a .readonly property which returns a copy of the array 
reference with the bit set

- optionally, arrays get a .needToWrite() method which does the 
following: { if (arr.isReadonly) arr=arr.dup; }  (yes, the name sucks)


Now this has the following (imho) neat properties:

- initial implementation should be quite trivial, I bet Walter could do 
it in a few hours; eventually, debug builds could prevent you from 
writing to a readonly array, but that's even not that important

- losing that one bit has no real effect on anything

- it can be tested for at runtime

- it has practically negligible impact on efficiency:
   - reading .length needs one instruction more (AND with 0x7fffffff)
   - setting .length needs about three instructions more
   - reading and writing to the array has no additional cost
   - moving the reference around also costs the same
   - new operations are quite trivial as well

- fits with COW perfectly

- there's no const-pollution and no need to write two versions of functions


A quick example of the possibilities:

char[] toUpper(char[] txt)
{
     for (int i=0; i<txt.length; i++) {
         char c = s[i];
         if ('a'<=c && c<='z') {
             txt.needToWrite();
             txt[i] = c-(cast(char)'a'-'A');
         }
     }
}

char[] FOO = toUpper("foo"); // constants are readonly, so COW is made

char[] bibi = getBibi(); // who owns it? I can finally know if it's me
char[] BIBI = toUpper(bibi); // write into bibi, if owned
char[] BIBI = toUpper(bibi.readonly); // leave bibi alone, as I need it


What y'all think?


xs0

PS:
Credits: the idea is not all mine, I got it from the discussion with 
Reiner Pope on D.learn

I'm also sorry if this was already suggested, but I don't remember 
anything of the sorts discussed..



More information about the Digitalmars-d mailing list