Memory allocation in D (noob question)

Sean Kelly sean at f4.ca
Wed Dec 5 07:55:34 PST 2007


Steven Schveighoffer wrote:
> "Regan Heath" wrote
>> 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...
> 
> The problem is that invariant data is changing.  This is a no-no for pure 
> functions which Walter has planned.  If invariant data can change without 
> violating the rules of the spec, then the compiler implementation or design 
> is flawed.  I think the design is what is flawed.

One could argue that invariant data is changing because of a programmer 
error, but you have a point.

> I have several problems with this concat operator issue.
> 
> First, that x ~= y does not effect the same behavior as x = x ~ y.  This is 
> a fundamental flaw in the language in my opinion.  any operator of the op= 
> form is supposed to mean the same as x = x op y.  This is consistent 
> throughout all of D, except in this case.
> 
> Second, there is the issue of the spec.  The spec clearly states that 
> concatenation should result in a copy of both sides.  Obviously, this isn't 
> true in all cases.  The spec should be changed for both D 1.x and 2.x 
> IMMEDIATELY to prevent unsuspecting coders from using ~= when what they 
> really want is just ~.

Or the runtime could be changed to always copy.  However, it would 
absolutely murder application performance for something like this:

char[] buf;
for( int i = 0; i < 1_000_000; ++i )
     buf ~= 'a';

And looping on an append is a pretty typical use case, in my experience.

> Third, I have not seen this T[new] operator described anywhere, but I am 
> concerned that D 1.0 will not be updated.  This leaves all coders who are 
> not ready to switch to D 2 at risk.  But from the inferred behavior of 
> T[new], I'm expecting that this will probably fix the problem.

The T[new] syntax basically said that resizable arrays would be declared 
as T[new] and non-resizable slices would be declared as T[].  My major 
problem with this is that it would change the way normal arrays are 
declared, and break tons of code in the process.


Sean



More information about the Digitalmars-d mailing list