Array literals MUST be immutable.
Michael Rynn
michaelrynn at optusnet.com.au
Wed Feb 17 16:30:32 PST 2010
On Wed, 17 Feb 2010 07:49:09 -0600, Andrei Alexandrescu wrote:
> Don wrote:
>> This is for me the last remaining D2 issue. I've mentioned this several
>> times before. Mutable array 'literals' are wrong on so many levels.
>> Here are some of the issues, listed in decreasing importance.
> [snip]
>
> I agree. How do you see we should change the language to fix things?
>
> Andrei
I am trying to improve my understanding here by reasoning some of it out
a bit, and trying to figure out what is everyone elses probably
implicitly understands.
Start looking at DPL C heritage, what is the behaviour of array literals
in C? What does a good C compiler do?
Whenever we put something like this in code,
Elem* = [ Piece of literal data ]
The compiler has created a representation of the data which of these?
1. pointer to protected read - only memory? (Probably would declare const)
2. returned a pointer to a writeable static memory location in the code-
data image, which is start of the array data. If so then the data can be
changed but not extended in size without reallocation.
3. allocated a copy of the original data, location known only to
compiler, to heap or stack allocated memory block, and assigned to the
pointer variable.
How does this vary with static and stack context?
I would like to (wishfully) think that what happens is that it looks like
the code text in my editor. The value of the literal in my source code
after being assigned is not destroyed by further manipulation of Elem*.
It still exists in the original source, so it should still exist in the
binary image, and can be recalled again. So thats what I would define as
the "immutable source".
This happens now for string type, they are source immutable. Changes can
be only done to a mutable copy. I have got used to that.
So what would really break if this was true of all array literals?
How hard is it to do in the current D2 compiler?
How does it affect the runtime typeinfo system? (I am still getting used
to that).
Has anyone tried this in an experimental version of D2?
I suppose we can always write code that can copy from immutable source
where necessary? Is it possible to be able make mutable copies more
easily?
Is there anything that is really awkward in D2 working with immutable
string type, that cannot be done without resorting to mutable character
literals? If not, then the principle can be applied to all "immutable
source".
But for those who would like mutable static memory initialised for some ,
might there be a way of telling the compiler that we wish to abuse the
memory image?
char[] = cast(mutable(char)[]) "I can overwrite this initialization
string for all time"; // points to original binary image
char[] = "I can overwrite this source string".dup;
The example given :-
int*[] foo(int *p)
{
return [p, p + 1];
}
I like to spell this out. This function reads to me as returning a copy
of the entire StaticArray of 2 pointers (8 bytes in 32bit OS) constructed
on the stack. It must return copy. Also [p, p + 1] is not a literal. Its
a dynamically constructed static array created by compiler magic (I do
like the magic). It therefore should not be a immutable array.
[&static1, &static2] might be an immutable array created in the binary
image.
Am I too pedantic or what?
Michael Rynn...
More information about the Digitalmars-d
mailing list