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".