dynamic arrays of immutable question: Are the elements actually mutable

Jonathan M Davis jmdavisProg at gmx.com
Wed Jan 9 13:15:48 PST 2013


On Wednesday, January 09, 2013 17:22:25 ollie wrote:
> On Wed, 09 Jan 2013 14:38:13 +0100, monarch_dodra wrote:
> > On Wednesday, 9 January 2013 at 12:38:13 UTC, Jonathan M Davis wrote:
> >> When you append to array, the elements being added are in untyped
> >> memory. So,
> >> no mutation of immutable anything is going on at all.
> > 
> > Ok, I guess that makes sense.
> 
> Newbie answer and question to follow.
> 
> The area of memory after .length to .capacity is not defined (untyped) in
> the D spec. It is a trick used by the compiler to not slow down appends
> with repetitive memory allocations. I believe that since the memory has
> been allocated for an array of a certain type, the extra capacity memory
> should be of that type until the array and its slices have been
> deallocated by druntime.
> 
> My question is about immutable and casting in general. I've heard Walter
> say of immutable, "Turtles all the way down.". If say I have a plug-in
> system with a defined interface and I pass it an immutable array (ie
> immutable(int)[]) then it uses a cast to mutate, that seems to defeat the
> purpose of immutable. When the plug-in returns, I now have an immutable
> array that has been mutated. Is this how immutable and casting are
> supposed to work?

If you mutate a variable after casting away either const or immutable, it's 
undefined behavior (unlike C++). Don't do it. You're breaking the type system 
when you do and will end up with bugs. It's possible, because D is a systems 
language, and if you know exactly what you're doing, you can get away with it 
under some circumstances, but it's still undefined behavior, and the compiler 
is free to assume that immutable data _never_ changes, so even if the data is 
not in read-only memory (if it were, mutating it after casting away immutable 
would likely result in a segfault), you'll end up with nasty bugs if you cast 
away immutable to mutate it, because the compiler will optimize code based on 
the assumption that the data will never change.

http://stackoverflow.com/questions/4219600/logical-const-in-d/4221334

The _only_ cases where it generally might make sense to cast away immutable is 
if you're passing data to a C function which you _know_ won't mutate it but 
unfortunately doesn't use const in its signature or when you're using 
std.concurrency - in which case, you can get away with casting an object to 
immutable to pass it across threads and then casting immutable away again as 
long as you _know_ that the original thread doesn't keep any references to the 
object. But even then, you really should be using shared for that rather than 
immutable, but there's a bug that prevents shared from currently working with 
std.concurrency like it should.

D's const and immutable provide hard guarantees, so casting them away is
generally just begging for trouble, because then _you_ must guarantee the
same things that the compiler normally would.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list