www.digitalmars.com         C & C++   DMDScript  

D - switch statement

reply James Gilbert <jgrg sanger.ac.uk> writes:
Hi,

I really like the sound of "D".  I quite like Java,
but it takes for ever to compile and run, and C++
is just a mess.  If only there was a language with
a nice clean OO syntax, which would compile and run
as fast as C.  Hey, it sounds like "D" is it!

Reading through the spec, I am very happy to see
so many C language annoyances fixed.  But how about
fixing the switch statement?  I don't think
fall-through should be the default behaviour - surely
the default should be a break.  I'd advocate
something like:

    switch (i)
    {
        case 1:
            x = 3;
            fallthrough;
        case 2:
            x = 4;
        case 3:
            x = 5;
    }

Instead of:

    switch (i)
    {
        case 1:
            x = 3;
        case 2:
            x = 4;
            break;
        case 3:
            x = 5;
            break;
    }

Less typing, and the default action is the
most common one.  (Idea from "Expert C
Programming" by Peter van der Linden, page
34 onwards.  Great book!)

Just my $0.02,  James
Aug 28 2001
next sibling parent reply "John Waggenspack" <jwag ieee.org> writes:
Sounds good but my most common use of fallthrough is this:

switch (i)
{
    case 1:
    case 2:
        x = i;
        break;
    case 3:
    case 4:
        x = i + 1;
        break;
}

I would like the above to be a special case of fallthrough that didn't
require the fallthrough keyword.

jwag

"James Gilbert" <jgrg sanger.ac.uk> wrote in message
news:3B8B80D0.48C7F694 sanger.ac.uk...
 Reading through the spec, I am very happy to see
 so many C language annoyances fixed.  But how about
 fixing the switch statement?  I don't think
 fall-through should be the default behaviour - surely
 the default should be a break.  I'd advocate
 something like:

     switch (i)
     {
         case 1:
             x = 3;
             fallthrough;
         case 2:
             x = 4;
         case 3:
             x = 5;
     }

Aug 28 2001
parent reply "Richard Krehbiel" <rich kastle.com> writes:
"John Waggenspack" <jwag ieee.org> wrote in message
news:9mgdcr$1cej$1 digitaldaemon.com...
 Sounds good but my most common use of fallthrough is this:

 switch (i)
 {
     case 1:
     case 2:
         x = i;
         break;
     case 3:
     case 4:
         x = i + 1;
         break;
 }

 I would like the above to be a special case of fallthrough that didn't
 require the fallthrough keyword.

I think this could be accomodated simply enough with a small syntactic change: switch(i) { case 1, 2: // ... case 3, 4: And, I'm not too crazy about the keyword "fallthrough". Why not "continue?" It's already a reserved word. And, we don't have to worry about legacy code with a legit "continue" within a switch. Oh - I'd suggest continuing to use "break" to mean "exit from switch" in this context. Have we addressed labelled "break" and "continue" statements yet? Like this: switch name (i) { // complex nested algorithms... break name; } Allow the same syntax with "for", "while", and "do", of course. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 home.com (personal)
Aug 28 2001
next sibling parent James Gilbert <jgrg sanger.ac.uk> writes:
Richard Krehbiel wrote:
 
 "John Waggenspack" <jwag ieee.org> wrote in message
 news:9mgdcr$1cej$1 digitaldaemon.com...
 Sounds good but my most common use of fallthrough is this:

 switch (i)
 {
     case 1:
     case 2:
         x = i;
         break;
     case 3:
     case 4:
         x = i + 1;
         break;
 }

 I would like the above to be a special case of fallthrough that didn't
 require the fallthrough keyword.

I think this could be accomodated simply enough with a small syntactic change: switch(i) { case 1, 2: // ... case 3, 4:

Yes, this seems neat.
 And, I'm not too crazy about the keyword "fallthrough".  Why not "continue?"
 It's already a reserved word.  And, we don't have to worry about legacy code
 with a legit "continue" within a switch.

I don't care about the keyword. As you have to explicity fall through.
 Oh - I'd suggest continuing to use "break" to mean "exit from switch" in
 this context.
 
 Have we addressed labelled "break" and "continue" statements yet?  Like
 this:
 
 switch name (i)
 {
     // complex nested algorithms...
         break name;
 }
 
 Allow the same syntax with "for", "while", and "do", of course.

Yes, these are "already implemented" for "for" and "while". -- James G.R. Gilbert The Sanger Centre Wellcome Trust Genome Campus Hinxton Cambridge Tel: 01223 494906 CB10 1SA Fax: 01223 494919
Aug 28 2001
prev sibling parent reply Russ Lewis <russ deming-os.org> writes:
Richard Krehbiel wrote:

 I think this could be accomodated simply enough with a small syntactic
 change:

 switch(i)
 {
     case 1, 2:
         // ...
     case 3, 4:

If we're going to do this, we should also allow ranges: switch(c) { case 'a'...'z','A'...'z': // .... }
 And, I'm not too crazy about the keyword "fallthrough".  Why not "continue?"
 It's already a reserved word.  And, we don't have to worry about legacy code
 with a legit "continue" within a switch.

I thought about suggesting just this...but I don't really think it's a good idea. continue already has a meaning that is something like "jump to next iteration of the loop". I think that it would, in the long run, be confusing to overload its meaning as "fall through." Kind of like static was overloaded ad nauseum... What about using goto? Could the 'case x' be seen as a label? switch(c) { case '0'...'9': foo(); goto case 'a'...'z','A'...'Z'; case 'a'...'z','A'...'Z'; bar(); goto default; default: baz(); }; While I don't like retyping those complex case ranges (copy-paste isn't too bad), it does have the upside of making it *very* easy to read and understand where you're going to.
Aug 28 2001
next sibling parent reply Chris Friesen <cfriesen nortelnetworks.com> writes:
Russ Lewis wrote:

 If we're going to do this, we should also allow ranges:
 
 switch(c)
 {
     case 'a'...'z','A'...'z':
      // ....
 }

Amen! I suggested this a while back.
 What about using goto?  Could the 'case x' be seen as a label?
 
 switch(c)
 {
     case '0'...'9':
        foo();
        goto case 'a'...'z','A'...'Z';
 
     case 'a'...'z','A'...'Z';
        bar();
        goto default;
 
     default:
         baz();
 };

ick. I REALLY don't want to have to type that much, even with cut and paste. A 'fallthrough' keyword is completely satisfactory to me, and is very obvious as to what it does. -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com
Aug 28 2001
parent Russ Lewis <russ deming-os.org> writes:
Chris Friesen wrote:

 Russ Lewis wrote:

 If we're going to do this, we should also allow ranges:

 switch(c)
 {
     case 'a'...'z','A'...'z':
      // ....
 }

Amen! I suggested this a while back.
 What about using goto?  Could the 'case x' be seen as a label?

 switch(c)
 {
     case '0'...'9':
        foo();
        goto case 'a'...'z','A'...'Z';

     case 'a'...'z','A'...'Z';
        bar();
        goto default;

     default:
         baz();
 };

ick. I REALLY don't want to have to type that much, even with cut and paste. A 'fallthrough' keyword is completely satisfactory to me, and is very obvious as to what it does.

Just occurred to me that it could be simpler; in the goto mention *any* valid value to jump to the case that would handle that value: switch(c) { case '0'...'9': foo(); goto case 'a'; case 'a'...'z','A'...'Z'; bar(); goto default; default: baz(); }; That reduces the typing A LOT. And yes, I know (and firmly believe in) Goto Considered Harmful...I just wonder if 'goto' isn't more readable than 'continue' and doesn't require a new keyword like 'fallthrough'.
Aug 29 2001
prev sibling parent reply Dan Hursh <hursh infonet.isl.net> writes:
Russ Lewis wrote:
 
 Richard Krehbiel wrote:
 
 I think this could be accomodated simply enough with a small syntactic
 change:

 switch(i)
 {
     case 1, 2:
         // ...
     case 3, 4:

If we're going to do this, we should also allow ranges: switch(c) { case 'a'...'z','A'...'z': // .... }

Well, I should let more knowledgeable people answer this, but they are probably getting tired. If my understanding of switch is correct, he is a pretty thin abstraction of what the compiler is actually doing in assembler (much like every flow control structure in C). It was a technique used in assembler for choosing between code locations to jump to. For your example above, the C syntax would be like: switch(c){ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': . . . } To the eye this is ugly. Nobody would write this because it is absolutely evil code. Coincidentally, from what I understand (and I could be wrong) but the generated code that matches is equally ugly. Either the compiler writer would have to have some special optimize that would translate this into something faster (like in if type structure) or let the compiler spite out nasty code for something that looks simple. I think the plan for D is to try to keep the syntax like C unless we are correcting a side effect issue. This will help people adjust to the language and int this case it will probably keep the compiler simpler (another goal so that it is easy to implement a complete and correct D compiler). Switch's fallthrough is not a side effect. It's just not a popular feature in modern high level languages. Also, there a mess of C/C++ and I believe Java programmers (Java has this syntax right?) who already use this syntax. Changing the behavior of switch would be like changing the behavior of typedef. (err... wait a moment...?) Also, in the example above, you have a range of characters. Number are fine semantically, but with character you have an added problem. For instance, if you support the systems native character set, and that system is one of the crusty mainframes, you might be in for a surprise. I believe some character sets do not have all the letters of the alphabet ordered contiguously. You might get some punctuation in that. Does the compile assume ascii, unicode, the locale favorite, etc.?
 And, I'm not too crazy about the keyword "fallthrough".  Why not "continue?"
 It's already a reserved word.  And, we don't have to worry about legacy code
 with a legit "continue" within a switch.

I thought about suggesting just this...but I don't really think it's a good idea. continue already has a meaning that is something like "jump to next iteration of the loop". I think that it would, in the long run, be confusing to overload its meaning as "fall through." Kind of like static was overloaded ad nauseum... What about using goto? Could the 'case x' be seen as a label? switch(c) { case '0'...'9': foo(); goto case 'a'...'z','A'...'Z'; case 'a'...'z','A'...'Z'; bar(); goto default; default: baz(); }; While I don't like retyping those complex case ranges (copy-paste isn't too bad), it does have the upside of making it *very* easy to read and understand where you're going to.

Given my argument above, I find arguing this moot. Oh heck, I like to argue. Goto is ugly. There I've said it. It has it's uses but it shouldn't have that many. How about this? We add some way to allow the programmer to say he wants break to be the default, in which case he would use continue (because it's breaks counterpart in loops, not because I'm biased toward continue or against the horribly ugly goto syntax requiring a label name). We could maybe put a flag of some sort after the switch condition and before the opening brace. That would allow masochists like you to declare you want pain and let the rest of use normal people continue living oblivious to your lifestyle choices. :-) Dan
Aug 28 2001
parent reply Chris Friesen <cfriesen nortelnetworks.com> writes:
Dan Hursh wrote:

 For your example above, the C syntax would be like:
         switch(c){
                 case 'a': case 'b': case 'c': case 'd':
                 case 'e': case 'f': case 'g': case 'h':
                 .
                 .
                 .
         }
 
 To the eye this is ugly.  Nobody would write this because it is
 absolutely evil code.  Coincidentally, from what I understand (and I
 could be wrong) but the generated code that matches is equally ugly.
 Either the compiler writer would have to have some special optimize that
 would translate this into something faster (like in if type structure)
 or let the compiler spite out nasty code for something that looks
 simple.

Any optimizing compiler already knows how to convert switches to if statements if it thinks it would speed things up. Converting ranges is just another thing to check, and it makes the code a lot easier to read. There are other languages that currently support ranges in switch/case statements. I think that you're working too hard to keep D like C. I would say that the vast majority of the time (even in C) the desired behaviour is to break. If this is true, then lets make it the default behaviour, and it can then be overridden by a 'fallthrough' statement. Anything that a) makes it easier to read, b) makes it easier to program, c) means less typing, d) makes sense, and e) is relatively simple to implement should, in my books, be included regardless of whether it is like C/C++. -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com
Aug 29 2001
parent reply Dan Hursh <hursh infonet.isl.net> writes:
Chris Friesen wrote:

 
 I think that you're working too hard to keep D like C.  

Nothing worth doing is ever easy. :-)
 I would say that the
 vast majority of the time (even in C) the desired behaviour is to break.  If
 this is true, then lets make it the default behaviour, and it can then be
 overridden by a 'fallthrough' statement.

I would still rather continue or the goto (where you only have to give one case and not the whole range).
 Anything that a) makes it easier to read, b) makes it easier to program, c)
 means less typing, d) makes sense, and e) is relatively simple to implement
 should, in my books, be included regardless of whether it is like C/C++.

Would it be good to at least add the need for braces around a case? The case labels look like goto label, and it looks like it is going to fall through. Maybe that's my C background, but labels don't look like block delimiters to me. switch(c){ case 'a': case 'b': { } case 'c': case 'd': { } } I just had an idea. switch (c){ case 'a': case 'b':{ // code for 'a' & 'b' } case 'c': case 'e':{ // code for 'c' & 'e' case 'f':{ // cade for 'f', 'c' & 'e' } // more code for 'c' & 'e' } default:{ // code for anything but 'a', 'b', 'c', 'e' & 'f' } } Thoughts? Good? Bad? Ugly? Plagiarized? Dan
Aug 29 2001
next sibling parent reply "Richard Krehbiel" <rich kastle.com> writes:
Oh, I just had a thought.

One of the common mistakes in C is to misspell "default," so that the
compiler then considers it a goto label.  Your default case code silently
disappears.  Can we make this problem go away?

Maybe by requiring "case default:" rather than just "default".  Maybe use
"case else" which is easier to spell, and also returns the word "default" to
user-identifier space.  Maybe by *requiring* the compiler to diagnose
goto-labels that aren't used.

I dunno, just do something, it's irritating.  Like the forgotten "break" is
irritating.

--
Richard Krehbiel, Arlington, VA, USA
rich kastle.com (work) or krehbiel3 home.com (personal)
Aug 30 2001
parent James Gilbert <jgrg sanger.ac.uk> writes:
If we were to have (possibly optional) braces
around the switch contents, the compiler could
disallow goto labels outside:

switch (c) {
    case 1: {
        my_label: i++;  // Label allowed inside block
    }
    case 2: {
        j++;
    }
    defau1t: {  /* Bzzzt!
                   Label outside braces;
                   compile error */
        k++;
    }
}

Or maybe disallow goto labels inside switches
all together.  Maybe the switch statement should
look more like the other control structures, and
not use the colon:

switch (c) {
    case (1) {
        my_label: i++;  // Label allowed inside block
    }
    case (2,3,4) {
        j++;
    }
    case (in alpha_num) {   // alpha_num is associative array
        do_stuff(c);
    }
    default {
        k++;
    }
}

I like braces; I feel safe inside them.

	James

Richard Krehbiel wrote:
 
 Oh, I just had a thought.
 
 One of the common mistakes in C is to misspell "default," so that the
 compiler then considers it a goto label.  Your default case code silently
 disappears.  Can we make this problem go away?
 
 Maybe by requiring "case default:" rather than just "default".  Maybe use
 "case else" which is easier to spell, and also returns the word "default" to
 user-identifier space.  Maybe by *requiring* the compiler to diagnose
 goto-labels that aren't used.
 
 I dunno, just do something, it's irritating.  Like the forgotten "break" is
 irritating.
 
 --
 Richard Krehbiel, Arlington, VA, USA
 rich kastle.com (work) or krehbiel3 home.com (personal)

Sep 03 2001
prev sibling next sibling parent reply Russ Lewis <russ deming-os.org> writes:
Dan Hursh wrote:

         switch(c){
                 case 'a': case 'b': {

                 }
                 case 'c': case 'd': {

                 }
         }

If you're going to do this, do it in a more consistent C-style syntax (more like a for or while loop): switch(c) { case('a','b') { } case('c','d') { }; }; Hey - surely D includes labels for continue, as well as break, right? What about: switch(c) { case('a','b') { continue case('f'); } case('f') { } case('c','d') { } } Block-style switches also simplify some lookup tables: switch(c) { case('x') FooX(); case('y') FooY(); case('z') FooZ(); case(default) throw Exception("The character must be one of x,y,z"); }
Aug 31 2001
parent reply "Ben Cohen" <bc skygate.co.uk> writes:
In article <3B8FA4ED.EDED1476 deming-os.org>, "Russ Lewis"
<russ deming-os.org> wrote:


 Hey - surely D includes labels for continue, as well as break, right?
 What about:
 
 switch(c) {
   case('a','b') {
 
      continue case('f');
   }
   case('f') {
 
   }
   case('c','d') {
 
   }
 }

Yes, I like this. It means you don't have to use a new "fallthrough" keyword and D's syntax becomes more consistent.
 Block-style switches also simplify some lookup tables:
 
 switch(c)
 {
    case('x') FooX();
    case('y') FooY();
    case('z') FooZ();
 
    case(default) throw Exception("The character must be one of x,y,z");
 }

Do you mean that each case is a block (with implied break after each) rather than just a label -- more like in Pascal?
Aug 31 2001
parent reply Russ Lewis <russ deming-os.org> writes:
Ben Cohen wrote:

 Hey - surely D includes labels for continue, as well as break, right?
 What about:

 switch(c) {
   case('a','b') {

      continue case('f');
   }
   case('f') {

   }
   case('c','d') {

   }
 }

Yes, I like this. It means you don't have to use a new "fallthrough" keyword and D's syntax becomes more consistent.

Moreover, it's enough different from C syntax that it will be obvious to programmers that it's a new syntax. The argument for/against C-compatibility vanishes if we do it this way.
 Block-style switches also simplify some lookup tables:

 switch(c)
 {
    case('x') FooX();
    case('y') FooY();
    case('z') FooZ();

    case(default) throw Exception("The character must be one of x,y,z");
 }

Do you mean that each case is a block (with implied break after each) rather than just a label -- more like in Pascal?

Yeah, that's the idea.
Aug 31 2001
parent reply James Gilbert <jgrg sanger.ac.uk> writes:
Russ Lewis wrote:
 
 Ben Cohen wrote:
 
 Hey - surely D includes labels for continue, as well as break, right?
 What about:

 switch(c) {
   case('a','b') {

      continue case('f');
   }
   case('f') {

   }
   case('c','d') {

   }
 }

Yes, I like this. It means you don't have to use a new "fallthrough" keyword and D's syntax becomes more consistent.


Oops, should have read this before my last post. Yes, I like having it look more like the other C control structures, and this eliminates the misspelled "default" silent error. Do we really need the "continue" if we can list several alternatives for one case? There are other control structures that can be used for complex logic. switch (c) { case ('a','b','c') { count_abc++; } case (2,3,4) { count_234++; } default { count_other++; } }
 Moreover, it's enough different from C syntax that it will be obvious to
 programmers that it's a new syntax.  The argument for/against C-compatibility
 vanishes if we do it this way.
 
 Block-style switches also simplify some lookup tables:

 switch(c)
 {
    case('x') FooX();
    case('y') FooY();
    case('z') FooZ();

    case(default) throw Exception("The character must be one of x,y,z");
 }

Do you mean that each case is a block (with implied break after each) rather than just a label -- more like in Pascal?

Yeah, that's the idea.

Sep 03 2001
parent reply Russ Lewis <russ deming-os.org> writes:
James Gilbert wrote:

 Russ Lewis wrote:
 Ben Cohen wrote:

 Hey - surely D includes labels for continue, as well as break, right?
 What about:

 switch(c) {
   case('a','b') {

      continue case('f');
   }
   case('f') {

   }
   case('c','d') {

   }
 }

Yes, I like this. It means you don't have to use a new "fallthrough" keyword and D's syntax becomes more consistent.


Oops, should have read this before my last post. Yes, I like having it look more like the other C control structures, and this eliminates the misspelled "default" silent error. Do we really need the "continue" if we can list several alternatives for one case? There are other control structures that can be used for complex logic.

We don't *need* it, but it would be useful. I often come across things like: if(a, b, c, or f is true) { if(a) doA(); else if(b) doB(); else if(c) doC(); doABCFCleanup(); } else if(d or e is true) { if(d) doD(); doDECleanup(); }; So continue isn't necessary, but would be useful.
Sep 04 2001
parent reply Charles Jenkins <cjenkins tec-usa.com> writes:
My two cents:

1. I like the idea of required braces instead of breaks. 
Break must still be permitted so that if statements within a 
case will work.

2. You don't need a fallthrough keyword if you have goto's. 
One enhancement might be to make labels inside of switch 
statements have the scope of the switch itself.

3. The ability to have multiple tests as part of a switch 
would be great! And you should also be able to test against 
any type, if possible.

Here's an intentionally-convoluted example of a switch with 
these features:

  switch ( c ) {
    case 'a': {
      Desired:
      // unique part of this case goes here
      goto AlwaysDo;
    }
    case ('b','c','d'): {
      Acceptable:
      // unique part of this case goes here
      goto Desired;
    }
    case ('e'): {
      // unique part of this case goes here
      AlwaysDo:
      // more stuff
    }
  } else {
    // default case
  }

The compiler should generate an error if a case has no 
enclosing braces or if no label can be found as the target 
of a 'goto' statement. Naturally, labels within the scope of 
the switch statement take precendence over labels with the 
same name in some outer scope.

PLEASE, whatever you do DON'T use the 'continue' keyword to 
modify the behavior of a switch; you need continue to behave 
exactly as in C, because switch statements are legal inside 
of loops!

  for ( i = 0; i < n; ++i ) {
    <snip>
    switch ( command ) {
      case CMD_SKIPONE: {
        ++i;
        continue;
      }
      <snip other cases>
    }
    <snip>
  }
Sep 04 2001
next sibling parent Charles Jenkins <cjenkins tec-usa.com> writes:
I don't know why my organization is listed as "Digital 
Mars" when I submit to this newsgroup. You should know that 
I am not in any way affiliated with Digital Mars, and so of 
course my opinions are my own and may differ dramatically 
from those of anyone who works at Digital Mars.

I'm using the Opera 5.11 web browser to interact with this 
newsgroup, and according to Opera, my email account is set 
up correctly with "TEC" as my organization.

I apologize in advance for any confusion that may arise from 
this matter; however, I don't currently know how to correct 
it.
Sep 04 2001
prev sibling next sibling parent Dan Hursh <hursh infonet.isl.net> writes:
Charles Jenkins wrote:
 PLEASE, whatever you do DON'T use the 'continue' keyword to
 modify the behavior of a switch; you need continue to behave
 exactly as in C, because switch statements are legal inside
 of loops!

Just to play devil's advocate, you are arguing to change how switch behaves so it is not like C. But you don't want to affect how a continue inside a switch behaves because it must be exactly as in C. I like the irony. Don't get me wrong, I understand the convenience of it, but since D has labeled breaks and continues, I'm not that worried. Actually, I'm intoxicated by the power of labeled breaks and continues. :-) Dan
Sep 04 2001
prev sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
In C, switch wasn't that useful in loops because you couldn't do a break out
of the loop from inside the switch.  If we remove the necessity for break
inside switch, that frees up the keyword for breaking from containing loops
again.

I'm perfectly happy with blocks instead of break.  And I'd rather use goto
or goto case than have implicit fallthru.  That frees up both break and
continue keywords.

I love the case ('b','c','e'..'h') { blah; } syntax, since that eliminates
99% of the cases where fallthrough was necessary and is cleaner and more
powerful than C's case.

Pascal had a lot of these things right.  One of the few things I hated about
Pascal were the wordiness, the special case for writeln, and lack of
objects/generics.  Didn't like the Pascal cast syntax, but C's is
troublesome too.  The builtin support for sets and ranges was wonderful.

Sean

"Charles Jenkins" <cjenkins tec-usa.com> wrote in message
news:1103_999632715 jenkins-lt...
 My two cents:

 1. I like the idea of required braces instead of breaks.
 Break must still be permitted so that if statements within a
 case will work.

 2. You don't need a fallthrough keyword if you have goto's.
 One enhancement might be to make labels inside of switch
 statements have the scope of the switch itself.

 3. The ability to have multiple tests as part of a switch
 would be great! And you should also be able to test against
 any type, if possible.

 Here's an intentionally-convoluted example of a switch with
 these features:

   switch ( c ) {
     case 'a': {
       Desired:
       // unique part of this case goes here
       goto AlwaysDo;
     }
     case ('b','c','d'): {
       Acceptable:
       // unique part of this case goes here
       goto Desired;
     }
     case ('e'): {
       // unique part of this case goes here
       AlwaysDo:
       // more stuff
     }
   } else {
     // default case
   }

 The compiler should generate an error if a case has no
 enclosing braces or if no label can be found as the target
 of a 'goto' statement. Naturally, labels within the scope of
 the switch statement take precendence over labels with the
 same name in some outer scope.

 PLEASE, whatever you do DON'T use the 'continue' keyword to
 modify the behavior of a switch; you need continue to behave
 exactly as in C, because switch statements are legal inside
 of loops!

   for ( i = 0; i < n; ++i ) {
     <snip>
     switch ( command ) {
       case CMD_SKIPONE: {
         ++i;
         continue;
       }
       <snip other cases>
     }
     <snip>
   }

Nov 04 2001
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
"Sean L. Palmer" wrote:

 In C, switch wasn't that useful in loops because you couldn't do a break out
 of the loop from inside the switch.  If we remove the necessity for break
 inside switch, that frees up the keyword for breaking from containing loops
 again.

Remember, though, that D has labeled breaks: WHILE_LOOP: while(blah) { SWITCH: swtich(bleh) { case 'a': foo(); break WHILE_LOOP; default: bar(); }; }; -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 05 2001
prev sibling parent "Ben Cohen" <bc skygate.co.uk> writes:
In article <3B8DBDCD.E9557EB3 infonet.isl.net>, "Dan Hursh"
<hursh infonet.isl.net> wrote:


 I just had an idea.
 
 
 	switch (c){
 		case 'a': case 'b':{
 			// code for 'a' & 'b'
 		}
 		case 'c': case 'e':{
 			// code for 'c' & 'e'
 			case 'f':{
 				// cade for 'f', 'c' & 'e'
 			}
 			// more code for 'c' & 'e'   **
 		}
 		default:{
 			// code for anything but 'a', 'b', 'c', 'e' & 'f'
 		}
 	}
 
 Thoughts?  Good?  Bad?  Ugly?  Plagiarized?

I think that this is valid in C, except that the case f doesn't break at the end of the block and continues to the ** code. I think the above code would be somewhat unclear, especially as the interpretation would be different from C's.
Aug 31 2001
prev sibling parent "Ben Cohen" <bc skygate.co.uk> writes:
In article <3B8B80D0.48C7F694 sanger.ac.uk>, "James Gilbert"
<jgrg sanger.ac.uk> wrote:

  I'd advocate something like:
 
     switch (i)
     {
         case 1:
             x = 3;
             fallthrough;
         case 2:
             x = 4;
         case 3:
             x = 5;
     }
 
 Instead of:
 
     switch (i)
     {
         case 1:
             x = 3;
         case 2:
             x = 4;
             break;
         case 3:
             x = 5;
             break;
     }
 
 

or fallthrough; each of these has problems. Why not have both break and fallthrough; cases which do not end in one of these should produce a compiler error. For example: switch (i) { case 1: x = 3; fallthrough; case 2: x = 4; break; case 3: x = 5; break; } This means that the code is clearer as it is always obvious what will happen. The fallthrough problem with C is eliminated, without producing a new break problem. Porting from C or Java to D will therefore be straightforward as you can just put fallthroughs in the places where the compiler complains. Other suggestions for switch syntax I liked include multiple cases/case ranges ("case 1..4, 7..10"), and the goto instead of break ("goto case 5"). I also fail to see how these can be combined neatly. I like the idea of replacing "default" by "else", perhaps in a separate clause like in Pascal: switch (i) { case 1: x = 3; fallthrough; case 2: x = 4; break; case 3: x = 5; break; } else { x = 0; }
Aug 30 2001