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