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



--- Comment #5 from bearophile_h...@eml.cc 2012-07-28 10:43:01 PDT ---
I have found another important use case for this diagnostic enhancement
request.

In my code three times or more I have put a not easy to find bug. Maybe the
original code was using nested dynamic arrays, or class instances:


void main() {
    auto data = [[10], [20], [30]];
    foreach (f; data)
        f[0]++;
}


And for some reason I replace the nested arrays with a struct or tuple:

import std.typecons: tuple;
void main() {
    alias tuple T;
    auto data = [T(10), T(20), T(30)];
    foreach (f; data)
        f[0]++;
}


The bug is that changes in f are not altering the array data. The correct code
is:


import std.typecons: tuple;
void main() {
    alias tuple T;
    auto data = [T(10), T(20), T(30)];
    foreach (ref f; data)
        f[0]++;
}



The C# language is designed to avoid this bug, because foreach on an array of
structs produces immutable structs. This is C# code:


struct F {
    public int x;
}
public class Test {
    public static void Main() {
        F[] data = {new F { x = 10 }, new F { x = 20 }, new F { x = 30 }};
        foreach (F f in data)
            f.x++;        
    }
}


The C# compiler gives:

test_s.cs(8,13): error CS1654: Cannot assign to members of `f' because it is a
`foreach iteration variable'
Compilation failed: 1 error(s), 0 warnings



A way to help avoid this bug in D is to add the unused last assignment warning:

import std.typecons: tuple;
void main() {
    alias tuple T;
    auto data = [T(10), T(20), T(30)];
    foreach (f; data)
        f[0]++;
}


A warning similar to:

temp.d(6): Warning: last assignment to f[0] is unused

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

Reply via email to