Memory allocation in D (noob question)

Regan Heath regan at netmail.co.nz
Wed Dec 5 03:06:20 PST 2007


Steven Schveighoffer wrote:
> "Sean Kelly" wrote
>> Steven Schveighoffer wrote:
>>> "Steven Schveighoffer" wrote
>>>> Another reason why this is seems to be a bug and NOT a feature:
>>>>
>>>>        string ab = "ab".idup;
>>>>        string a = ab[0..1];
>>>>        a ~= "c";
>>>>        writefln("ab = ",ab); // also outputs "ac"
>>>>
>>>> This changes an invariant string without compiler complaint!
>>> more bugs :)
>> This is expected behavior.

In this post I'm commenting on the example shown above, not the 2nd one 
(which to be honest is much more worrying).  I am a bit confused as to 
which example Sean was saying was "expected behaviour".

> Behavior by design, perhaps.  Expected, I should hope not.  I would never 
> expect to be able to have one variable overwrite another without obvious 
> casting.  

Both variables above are references to the same data.  You're using one 
variable to change that data, therefore the other variable which still 
refers to the same data, sees the changes.

If the concatenation operation had to reallocate the memory it would 
produce a copy, and you wouldn't see the changes.

So, this behaviour is non deterministic, however...

 > And why should it be 'expected behavior' for the GC to assume that
> because an array is at the beginning of a memory block, it is free to use 
> any memory in that block?  I think I've proven that there are cases where it 
> should not assume that.

The assumption fits with D's (semi-)official "copy on write" policy.  If 
you want to write to memory and you cannot be sure you are the only 
reference then you should copy the data before writing.

Following this guideline makes the behaviour deterministic, and...

> I'm not saying there is a bug in the compiler implementation, or that the 
> docs need to be changed to reflect the compiler behavior.  I'm saying the 
> design here is flat out wrong, and needs to be reflected in the compiler. 
> My recommendation would be to make the ~= behave exactly as the spec says, 
> that it always makes a copy of it's arguments.  If you need buffer-like 
> behavior for performance, write a new type.

The current behaviour allows you to skip the copy step if you _know_ you 
hold the only reference to the data, it's putting the choice/power in 
the programmers hands.  As always, power can be a dangerous thing if 
missused :)

> Isn't one of Walter's goal to prevent silent runtime errors?  IMO, memory 
> corruption errors are the worst kind of silent errors.

The example shown above is not corrupting any memory.  The 2nd one (not 
shown above) seems to be and it worries me much more.

Regan



More information about the Digitalmars-d mailing list