bug or feature?
Oskar Linde
oskar.lindeREM at OVEgmail.com
Tue Dec 5 09:42:16 PST 2006
Chris Nicholson-Sauls wrote:
> bobef wrote:
>> import std.stdio;
>> import std.string;
>>
>> void main()
>> {
>> char[] a;
>> char[][] b;
>> a~="1234";
>> b~=a;
>> a.length=0;
>> a~="&&";
>> b~=a;
>> a.length=0;
>> a~="asdf";
>> b~=a;
>> writefln(join(b," "));
>> }
>>
>> //outputs "asdf as asdf"
>>
>> //if we (replace a~="..." with a="...") || (replace a.length=0 with
>> a=null) || (replace b~=a with b~=a.dup) then it outputs "1234 && asdf"
>>
>> //i don't know if this is bug or new feature since last time i used d
>
> Its a side-effect of a feature, I believe. Setting an array's length to
> 0 no longer deallocates the array. And the ~= in this case is storing
> the current whole /slice/ of a into b. So its by design, but definitely
> a potential gotcha!
It is by design and works as intended. And you are right - it is a
gotcha that every new user to D must be aware of. The above example is
excellent in illustrating this.
The fundamental reason for this is that D has combined the two abstract
concepts, the array and the slice, as a hybrid: T[]
Those two concepts are unfortunately not 100 % compatible and this leads
to problems such as the one above. I'm sure this design decision will
come back and haunt D many times in the future.
To most people, the abstract concept of an array is "a set of elements
with a sequential order". D's dynamic array (T[]) has the side effect of
when changing, removing or adding elements in one array, other arrays
/may/ be altered. This must be surprising for anyone with only an
abstract array model in mind (a sequential set of elements).
There is only one sure way to prevent this - to strictly and manually
employ Copy on Write for all cases except when you can be sure that the
memory area used by the array is unique and writable. There is no help
from the compiler. D will not keep reference counts, give compile time
or run time warnings or even hold your hand. It even prevents you from
implementing your own automatic reference counts. The mantra is "If
unsure, dup."
The above code violates CoW twice, and thus the unexpected behavior.
/Oskar
More information about the Digitalmars-d-bugs
mailing list