June 28, 2013
This is deprecated according to dmd 64-bit linux, but no error message for Mac or Windows, and exhibits different runtime behavior on Windows to those other platforms, as I found out from my students using it in a current CS2 class.

Is there some reason why assigning to a non-ref foreach variable is permitted at all? Naively, it's a value from the loop's range, but not a variable, and so the compiler could treat it as such and forbid assignment.
June 28, 2013
Carl Sturtivant:

> Is there some reason why assigning to a non-ref foreach variable is permitted at all? Naively, it's a value from the loop's range, but not a variable, and so the compiler could treat it as such and forbid assignment.

I opened a discussion on this, and later an enhancement request, that the very good Kenji has done some improvements.

Currently this code compiles and runs:

void main() {
    import std.stdio;
    foreach (i; 0 .. 10) {
        i.writeln;
        i++;
    }
    writeln;
    foreach (ref i; 0 .. 10) {
        i.writeln;
        i++;
    }
}


That prints:

0
1
2
3
4
5
6
7
8
9

0
2
4
6
8


I think both are not so good.

Also in D this is a common bug:

struct S { int x; }
void main() {
    import std.stdio;
    auto data = [1.S, 2.S, 3.S];
    foreach (item; data)
        item.x++;
    data.writeln;
}


That prints:

[S(1), S(2), S(3)]

See some threads:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=155816

And some issues:
http://d.puremagic.com/issues/show_bug.cgi?id=5306
http://d.puremagic.com/issues/show_bug.cgi?id=6214
http://d.puremagic.com/issues/show_bug.cgi?id=6652

Thanks to Kenji the situation is improved compared to the past, but I think the current situation is not yet good enough...

Bye,
bearophile