Question

I have a bug in my current code that I have been banging my head against for a couple days. I'll post the summary version of the code below (not my actual code, but it still compiles).

#include <iostream>

using namespace std;

int main()
{
  int x = 7;

  switch(x)
  {
    case 1:
    {
      case 2:
      cout << "hi";
    }
  }
}

I like to sometimes introduce a tighter scope to my switch cases so local variable names don't interfere with ones I've used earlier. Apparently I had a phone call to answer or something one day and didn't finish writing the case statement as I wished, but later on was certain that I had. case 2 should have actually been in a nested switch, not as part of the original outter switch (for those wondering, I use named constants in my code, not just magic numbers). On g++, I didn't get a warning or error when compling without any options.

My question: why allow cross-scope case jumps from a switch? What purpose does it serve?

Was it helpful?

Solution

Duff's Device is hardly the "purpose" of cross-scope case labels as already suggested, it is merely an exploitation of it.

The truth is probably that it serves no intentionally designed purpose, but is merely an artefact of the most simple possible implementation that works. The design is such that the switch-case construct can do exactly what is reasonable, but does not explicitly protect you from the unreasonable either.

OTHER TIPS

The case labels are just labels, destinations for (compiler-generated) gotos.

In the same way as ordinary labels have function scope, case labels have switch scope.

The only reasonable advantage is Duff's Device, which however is not very relevant on modern computers.

So, it's historical.

A case of "frozen history".

Cheers & hth.,

That code compiles for historical reasons only.

Note that it could cause very bizarre versions of Undefined Behavior:

// don't try this at home
switch(x) {
  case 1:
  {
    std::string s = "hi!"
    case 2:
    cout << s; // doh!
  }
}

If x==2, this would access s without calling its constructor first. I'd expect compilers to warn about that, though.

Cross-scope case labels inside switch statements do serve a purpose, especially in real-time, embedded, system applications. For one thing, they allow cleaner implementations of couroutines. They also reduce or eliminate the use of goto statements in similar low-level applications. Yes, goto's are ugly but if you have written device drivers before where time and sync issues are the norm, you would appreciate the usefulness of cross-scope case labels over the high maintenance of goto statements. The lesser of two evils if you will.

Your code above is a synonym for:

switch (x)
{
     case 1:
     case 2:
     cout << "hi";
}

The compiler does not differentiate between this code and the code you posted in terms of the switch-case functionality. It's interpreting it as multiple case scenarios for the instructions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top