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