View mode: basic / threaded / horizontal-split · Log in · Help
June 30, 2010
Final switch statement
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
Top | Discussion index | About this forum | D home