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