On Tuesday, 1 January 2013 at 17:52:20 UTC, bearophile wrote:
A small quiz (it's a reprise of an older discussion). This code compiles with no errors, but do you see anything wrong here?


// -----------------
struct Foo {
    int x;
    alias this = x;
}

class Bar {
    Foo[] data;

    this() {
        data.length = 10;
    }

    Foo opIndex(uint i) {
        return data[i];
    }

    void opIndexUnary(string op)(uint i) if (op == "++") {
        data[i]++;
    }

    void opIndexUnaryRight(string op)(uint i) if (op == "++") {
        data[i]++;
    }
}

void main() {
    auto barfoo = new Bar;
    ++barfoo[3];
    assert(barfoo.data[3] == 1);
    barfoo[3]++;
    assert(barfoo.data[3] == 2);
}
// -----------------


Do you think this code should produce some compilation errors?

Bye,
bearophile

YES. Or should I say: There needs to be a way to diagnose these kinds of errors. I think there should be a "operator" keyword to protect yourself. I'd prefer it be mandatory, but even introducing it as optional would help:

//----
operator void opIndexUnaryRight(string op)(uint i);
//----
Error: No operator opIndexUnaryRight. Perhaps you meant opIndexUnary?
//----

This is especially improtant in that sometimes, the operator name is a guessing game...

==========================================
Related: I fixed a similar bug in std.container.DList recently: Can you spot the error?

//----
DList opOpassign(string op, Stuff)(Stuff rhs)   
if (op == "~" && is(Stuff == DList))
//----

The fact that it made it into the standard library is, IMO, a tell tale sign of a big problem. A "smoking gun".

Reply via email to