[Issue 20901] arrays confuse static foreach

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Jun 7 22:38:28 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=20901

Simen Kjaeraas <simen.kjaras at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simen.kjaras at gmail.com

--- Comment #1 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
A shorter piece of code that demonstrates the issue:

import std.stdio : writeln;
struct S {
    int[] front = [0];
    bool empty() { return front[0] >= 2; }

    void popFront() {
        front[0]++;
    }
}

void main() {
    static foreach (e; S()) {
        writeln(e); // Writes [2] 2 times
    }
}


What happens is somewhat equivalent to this:

// Happens at compile-time:
S tmp;
auto value1 = tmp.front;
tmp.popFront();
auto value2 = tmp.front;
tmp.popFront();

// Happens at run-time:
writeln(value1);
writeln(value2);

Since there is no .dup anywhere to be found, value1 and value2 refer to the
same array, so popFront() modifies both. Since all calls to popFront() happen
at compile-time, before any of the values are used, only the final values are
available. In fact, a deep duplication would be required for the values to be
correct, which could cause other issues where you expect changing a value in
one step would carry over to the next.


So, static foreach does not deal well with ranges that modify referenced data,
and I'm not sure this is an issue that can be properly fixed. static foreach
looks like 'please unroll this loop', but is... something else.

--


More information about the Digitalmars-d-bugs mailing list