Changing elements during foreach

qznc qznc at web.de
Mon Oct 21 22:10:24 PDT 2013


On Monday, 21 October 2013 at 20:14:09 UTC, ixid wrote:
> On Monday, 21 October 2013 at 19:37:47 UTC, Jonathan M Davis 
> wrote:
>> On Monday, October 21, 2013 21:16:00 qznc wrote:
>>> On Monday, 21 October 2013 at 16:22:29 UTC, Krzysztof Ciebiera
>>> 
>>> wrote:
>>> > I understand slices now and I don't find it consistent with 
>>> > "no
>>> > shoot in the foot by default" statement.
>>> 
>>> I agree. The pitfalls are well understood, yet everybody 
>>> seems to
>>> love them. Ok, compared to C array they are an improvement 
>>> due to
>>> bounds checking. If the elements are const or immutable 
>>> (string)
>>> everything is fine, but write+append is basically
>>> implementation-defined behavior.
>>> 
>>> Once there is a proper std.collections, I will probably adapt 
>>> my
>>> tutorial to recommend a safe alternative (ArrayList?).
>>
>> Just don't use slices when appending. It's only an issue when 
>> you're appending
>> and relying on slices continuing to refer to the same array, 
>> and that's not
>> going to work. Slices are primarily for reading, not writing. 
>> Using a
>> container doesn't change that. It just makes it so that you 
>> can't even attempt
>> to append to a slice, because the slice is a different type 
>> than that container
>> and won't support appending.
>
> What would be the issue/s with disallowing appending to slices? 
> So you'd have to explicitly duplicate before you could append.

Appending itself is not the problem. Append + write is 
indeterministic.

  int[] a = [1,2,3];
  int[] b = a;
  a ~= [4,5]; // append
  a[0] = 42; // write
  assert (b[0] == 42) // indeterministic, implementation-specific

It depends on the capacity during the append. If a reallocation 
happened, then b[0]==1. Otherwise b[0]==42.

If you can forbid the write (e.g. immutable(char)[] aka string), 
you can append as much as you want. If you can disallow the 
append (convention, no type system support for this), you can 
write as much as you want.

For something like Javas ArrayList, the behavior would be a 
deterministic b[0]==42, but also a.length==b.length.


More information about the Digitalmars-d-learn mailing list