Memory allocation in D (noob question)

Sean Kelly sean at f4.ca
Tue Dec 4 08:40:25 PST 2007


Steven Schveighoffer wrote:
> "Oskar Linde" wrote
>> Try this:
>>
>>         char[] ab = "ab".dup;
>>         char[] a = ab[0..1];
>>         a ~= "c";
>>         writefln("ab = ",ab);
> 
> Outputs "ac"
> 
> So this appears to be a bug then.  Because from the spec:
> 
> "Concatenation always creates a copy of its operands, even if one of the 
> operands is a 0 length array"

Then the spec is wrong.  The current behavior is very deliberate, 
insofar as the code is concerned.  Look at internal/gc/gc.d.  It is also 
deliberate for interior slices to always reallocate on an append.  But 
the runtime has no way to know whether something pointing to the head of 
a block is a slice or is the original array.  I've never actually found 
this to be a problem in practice, and I'll admit to having used the 
slice terminology from time to time, because it's more succinct than 
resizing using the length property.

>>>> So appending to the [$..$] array would (without padding) mean that you 
>>>> corrupt the following array.
>>> I think this is incorrect for the reasons I stated above.  An allocated 
>>> block should never be re-assigned to another array.
>> See my example above. The allocated block is deduced from the slice .ptr. 
>> If the pointer points at the start of another array, DMD would have no way 
>> of knowing it isn't a slice of that other array.
> 
> I think your example exposes a bug, and does not agree with what the spec 
> says.

The spec also says that D 1.0 has inheritable contracts, and maybe we 
will one day, but it's not even on the radar at the moment.  For better 
or worse, I've learned not to put much stock in what the spec says about 
some things.

> There seems to be a silent agreement among everyone that D should behave 
> that way, but I can't find anything in the spec that states it should.  Is 
> this something that is planned to be fixed or at least described correctly 
> in the spec?
> 
> If someone desires this behavior, I would say that it's possible to keep a 
> reference to the entire array and use the copy operator.  i.e.:
> 
> ab[1..$] = "c";
> 
> perhaps there could be another way to extend the slice if more buffer space 
> exists?

It would be easy to allow all slices to be extended in place, even the 
interior ones.  But going the other direction would be difficult.  The 
proposed T[new] syntax might help in that direction, but I hate it.


Sean



More information about the Digitalmars-d mailing list