Is remove safe using foreach

Steven Schveighoffer schveiguy at gmail.com
Tue Dec 13 15:15:59 UTC 2022


On 12/13/22 6:22 AM, Per Nordlöw wrote:
> On Monday, 12 December 2022 at 17:29:00 UTC, Steven Schveighoffer wrote:
>> Removing keys while iterating is not supported. It will break, in 
>> confusing ways, and possibly include a null pointer dereference.
> 
> IRC, the specs says that it's an error to modify a foreach aggregate but 
> the compiler curretly doesn't diagnose it.

It does say this, but the explanation is misleading. The aggregate must 
be *loop invariant*, which means that modifying the aggregate must not 
affect the current iteration state. However, the exact words are:

 > The aggregate itself must not be resized, reallocated, free'd, 
reassigned or destructed while foreach is iterating over the elements.

However, comically, just after the example it has this note:

 > Note: Resizing or reassigning a dynamic or associative array during 
foreach is still @safe.

Which both contradicts the direct words in the rule, and is wrong in the 
case of resizing an associative array (which can easily mess up the 
foreach iteration).

In reality, the only thing that should be disallowed is invalidating the 
foreach iteration as defined on the original. How this is enforced is 
implementation defined by the *object itself*. The compiler cannot know 
how iteration interacts with an aggregate, so it is on the aggregate to 
define the rules.

As an example, I specifically allowed removal of the currently iterating 
element in my container library, dcollections. The mechanism used was 
opApply with a ref bool that you would set if you wanted to remove the 
element after that loop iteration. This did not change which elements 
were iterated over, so it was loop invariant.

Array and AA iteration rules should be clearly defined. And the general 
rules should be adjusted to delegate iteration restrictions to the 
aggregate, provided the iteration is still loop invariant.

I'll see if I can create a PR to reword the restrictions.

-Steve


More information about the Digitalmars-d-learn mailing list