[Issue 2255] AA.remove() doesn't remove AA element when iterating using foreach

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed May 25 03:24:55 PDT 2011


http://d.puremagic.com/issues/show_bug.cgi?id=2255



--- Comment #7 from bearophile_hugs at eml.cc 2011-05-25 03:20:31 PDT ---
This is similar Python2.6 code:


stuff = {}
for i in xrange(10000):
    stuff[i] = i
print len(stuff) # Should be 10_000
for k in stuff:  # Only this line is different between cases
    del stuff[k]
print len(stuff) # Should be 0


If you try to run it Python prints:

10000
Traceback (most recent call last):
  File "...\test.py", line 5, in <module>
    for k in stuff:  # Only this line is different between cases
RuntimeError: dictionary changed size during iteration


The underlying C implementation of this is simple: Python initializes a boolean
flag when you scan a dict/set with a for. And the del statement tests that flag
every time it is called. Such flag and test were added to Python because this
is a common mistake for new Python programmers, and Python tries hard
(successfully) to prevent the most common bugs.

That Python error message is useful not just to avoid a bug, but also to teach
new programmers to be aware of this problem more in general, even in other
languages that don't give this error message.

In D it's probably possible to set a flag of the associative array every time
the associative array iteration functions are used. But testing this flag every
time AA.remove()/AA.clear() get called is a bit costly for a system language. A
compromise is to set and test this flag only when you compile your code in
non-release mode, using a runtime assert. I think this may be acceptable and it
helps avoid some bugs (but to do this the associative array code needs to be
recompiled every time, it can't be in a statically compiled library).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list