6

The switch statement in C/C++ has an interesing feature that all subsequent blocks will be executed if a condition is met

For example,

int a = 2;
int b = a;
switch(b)
{
     case 1:cout<<1;
     case 2:cout<<2;
     case 3:cout<<3;
     case 4:cout<<4;
};

The above code will output 234 unless I put a break statement in case 2.

In 3 years(quite small,yeah) of my C/C++ programming experience, I have never encountered a problem where I had to use switch without putting break statments in every case. But judging by the fact that this feature has been stuck for so long, there might be some utility of it.

Question: What are some clever uses of switch statement as to utilize the above mentioned feature in C/C++?

Cheeku
  • 833
  • 1
  • 8
  • 22
  • 3
    I don't know what kind of clever uses you're looking for but you could read more on why `switch` requires `break` in this post: [Why was the switch statement designed to need a break?](http://stackoverflow.com/q/252489/1798187). as stated in that post, you may use this "feature" for fall through. – idanshmu Mar 17 '14 at 09:37
  • There are "problems", where several values could need to be handled the same way. And this is very specific to the "problem". That's too broad, IMO. – Kiril Kirov Mar 17 '14 at 09:37
  • Why this question is closed as primarily opinion based? I think its a valid question! – Rahul Tripathi Mar 17 '14 at 09:41
  • 1
    @user3414693 trying to find clever uses for some kind of `c++` ability is not really a standard `SO` question. – idanshmu Mar 17 '14 at 09:43
  • 1
    It really is not a standard SO question, but I won't classify it as based on opinion rather than facts. Maybe the word 'clever' misguides, but all I'm asking is uses for an apparent 'feature' in a programming language. Yes, I would have trouble marking a single answer as correct. – Cheeku Mar 17 '14 at 14:11

4 Answers4

7

Probably one of the most interesting use cases I have seen would be Duff's Device the case where you extend a scope within a switch over multiple cases which would look something like this:

void send( int *to, const int *from, int  count)
{
        int n = (count + 7) / 8;
        switch(count % 8) 
        {
            case 0: do {    *to = *from++;   // <- Scope start
            case 7:         *to = *from++;
            case 6:         *to = *from++;
            case 5:         *to = *from++;
            case 4:         *to = *from++;
            case 3:         *to = *from++;
            case 2:         *to = *from++;
            case 1:         *to = *from++;
                        } while(--n > 0);    // <- Scope end
        }
}
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Boost Asio's stackless coroutines come pretty close to this (modulo evil pointer arith) – sehe Mar 17 '14 at 09:39
  • 3
    Unfortunately, using a `goto` (which is what a `switch` boils down to) to jump into a loop is likely to throw the optimizer way off track. This can be much more detrimental to performance than the gains of Duff's Device. So, while Duff's Device once were a good optimization when it was invented, I wouldn't use it in new code. – cmaster - reinstate monica Mar 17 '14 at 09:53
6

This is usually used when you want to apply a similar action to a set of values. For instance, the following :

switch (event) {
   case DEVICE_DISCONNECTED:
   case CONNECTION_ERROR:
   case CONNECTION_TIMEOUT:
     transitionTo(disconnectedState);
     break;
   case CONNECTION_SUCCESS:
     transitionTo(connectedState);
     break;
}

is much more concise and readable in my opinion than :

switch (event) {
   case DEVICE_DISCONNECTED:
     transitionTo(disconnectedState);
     break;
   case CONNECTION_ERROR:
      transitionTo(disconnectedState);
     break;
   case CONNECTION_TIMEOUT:
     transitionTo(disconnectedState);
     break;
   // ... 
}
Halim Qarroum
  • 13,985
  • 4
  • 46
  • 71
6

In my current project, I have the following enumeration:

enum NodeType
{
  SCALAR, COMPOSITE, ARRAY, RESTRICTED_ARRAY
};

Thus, quite a few node-processing routines use this pattern:

switch (nodeType)
{
  case SCALAR:
    processScalar();
    break;
  case COMPOSITE:
    processComposite();
    break;
  case RESTRICTED_ARRAY:
    if (!handleRestrictions())
      return false;
    // continue to next case
  case ARRAY:
    processArray();
    break;
}

Note that it's almost necessary to always mark the lack-of-break as explicitly intended with a comment (like I did above) - future maintainers (including yourself in 3 months) will thank you.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
5

I've often used a construct to parse command line arguments like this:

switch (argument) {
    case arg_h:
    case arg__help:
    case arg_questionmark:
        printf("Help\n");
        break;
    case arg_f:
    case arg__file:
        //...
}

where argument is an enum type.

urzeit
  • 2,863
  • 20
  • 36