Final switch statement
bearophile
bearophileHUGS at lycos.com
Wed Jun 30 05:31:02 PDT 2010
Introducing a second kind of switch in D was bad because it's a special case, it duplicates a syntax already present, making the language more complex, etc. (one of the bigger faults of C++ is to have two ways to do everything, one inherited from C and one new). But given the constraints D is designed for (to keep the same semantics of C syntax or to disallow it), it can be acceptable even if inelegant.
I think the design of final switch needed more public discussions and more thinking.
One problem of the 'final switch' can be solved disallowing the automatic fall-through in both kinds of switch.
The current implementation of final switch seems to have some problems, I have done some tests below.
This is a normal usage of final switch, repeating the enum name into each case is not elegant, but it can be accepted:
void main() {
//static enum E1 { A, B } // wrong
enum ThisIsAnEnum { A, B }
E1 e1;
final switch(e1) {
case ThisIsAnEnum.A: break;
case ThisIsAnEnum.B: break;
}
}
It seems final switch doesn't "work" in this easy situation, and ignores the missing case 7 (final switch is not supposed to do this, so this is not a bug, but it can become an enhancement request):
void main() {
uint ui;
final switch(ui % 8) {
case 0: break;
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 5: break;
case 6: break;
}
}
If I have 256 values in a ubyte I can omit them all:
void main() {
ubyte u;
final switch(u) {
}
}
This shows that CaseRangeStatements are not allowed in a final switch, what's bad in a CaseRangeStatement? It's not bug-prone:
void main() {
ubyte u;
final switch(u) {
case ubyte.min: .. case 0: break;
case 1: .. case ubyte.max: break;
}
}
// test.d(4): Error: case ranges not allowed in final switch
Strings are allowed and "ignored":
void main() {
string s;
final switch(s) {
}
}
But string enums are not allowed, I don't know why (can this become another enhancement request):
void main() {
enum E2 : string { C="foo", D="bar" }
E2 e2;
final switch(e2) { // error: Error: 'e2' is not of integral type, it is a E2
case E2.C: break;
case E2.D: break;
}
}
I think a final switch like this is useless, because it currently can't contain CaseRangeStatements and default and it can't contain that many cases, so maybe it's better to disallow this:
void main() {
int i;
final switch(i) {
}
}
Bye,
bearophile
More information about the Digitalmars-d
mailing list