I've ran across code that looks like this:
switch(i) {
case 2: {
std::cout << "2";
break;
case 3:
std::cout << "3";
break;
}
case 4: {
std::cout << "4";
break;
}
}
Notice that case 2
opens a block with curly brace, which is closed only after case 3
. At first this seemed like a typo that would either cause a compiler error, or, even worse, ignore case 3
. But it works just fine in c++ and outputs 3 if i is 3. I come from java background so my understanding of logical blocks in c++ may be lacking. So my question is: is this deliberate behavior?
Yes, and just like that.
Also, you can write multiple statements in a case without using curly braces { }. As per the above syntax, switch statement contains an expression or literal value. An expression will return a value when evaluated. The switch can includes multiple cases where each case represents a particular value.
If two cases in a 'switch' statement are identical, the second case will never be executed. This most likely indicates a copy-paste error where the first case was copied and then not properly adjusted.
you can say a case inside case without its switch or preceded by a break will work the same way a label works.
You can, but shouldn't, abuse case labels in a switch
far worse than that — and far worse than Duff's Device. Duff's Device has the dubious privilege of being almost plausibly useful and yet can be regarded as abusing switch
.
Not all abuses of switch
can claim to be plausibly useful. For instance, this compiles as C or C++, even with stringent warnings set:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
unsigned seed;
if (argc == 2)
seed = atoi(argv[1]);
else
seed = time(0);
printf("seed: %u\n", seed);
srand(seed);
int i = rand() % 10;
int j = 21;
int k = 37;
printf("i: %d\n", i);
switch (i)
{
case 1:
for (j = 10; j > i; j--)
{
case 2:
printf("case 2:\n");
for (k = j - 1; k > 0; k--)
{
case 6:
printf("case 6:\n");
default:
printf("%d-%d-%d\n", i, j, k);
}
case 5:
printf("case 5:\n");
printf("%d-%d\n", i, j);
break;
}
break;
case 3:
printf("case 3:\n");
break;
}
return 0;
}
The argument handling allows you set the seed, so you can reproduce results if you want to. I'd make no claim that it is useful; indeed, it is not useful. Note that break
inside the loops breaks the loop, not the switch
.
Basically, case
labels (and default
) must be within the scope of a switch
, and are associated with the innermost enclosing switch
. There are few other constraints on them. You have to be careful not to jump over variable initializations, etc (that's why j
and k
are defined outside the switch()
). But otherwise, they're just labels, and control will flow to them when 'appropriate'.
switch
statement in C/C++ is a glorified goto
statement (with some optimization benefits).
As a result, you can do as much with case
labels as you'd do with goto
labels. In particular, jumping inside the block is allowed, as long as you are not bypassing any variable initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With