[Issue 2255] AA.remove() doesn't remove AA element when iterating using foreach
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Tue Nov 4 00:08:13 PST 2014
https://issues.dlang.org/show_bug.cgi?id=2255
yebblies <yebblies at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |yebblies at gmail.com
--- Comment #9 from yebblies <yebblies at gmail.com> ---
It's actually fairly easy to check for the most common cases (item removed or
inserted while iterating) by saving the length at the start of iteration, and
checking it hasn't changed before visiting each item. The check needs to be
before visiting, because it's safe to mutate the AA if the loop is exited right
after.
eg
diff --git a/src/rt/aaA.d b/src/rt/aaA.d
index cf4f139..5991393 100644
--- a/src/rt/aaA.d
+++ b/src/rt/aaA.d
@@ -545,10 +545,12 @@ int _aaApply(AA aa, in size_t keysize, dg_t dg)
immutable alignsize = aligntsize(keysize);
//printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa.impl,
keysi
+ auto startLength = aa.impl.nodes;
foreach (e; aa.impl.buckets[aa.impl.firstUsedBucketCache .. $])
{
while (e)
{
+ assert(aa.impl.nodes == startLength, "AA was modified during
iteration");
auto result = dg(cast(void *)(e + 1) + alignsize);
if (result)
return result;
The big problem is - this check should only be on in debug mode, but nobody
ever uses a debug build of druntime, so it would be useless. I don't even know
how to make debug build of druntime on win32.
--
More information about the Digitalmars-d-bugs
mailing list