how does this switch block executes? - c++

#include<bits/stdc++.h>
using namespace std;
void show(int errorCause)
{
switch(errorCause)
{
case 1:
{
cout<<"in 1\n";
break;
}
case 2: break;
case 3:
{
cout<<"in 3\n";
break;
case 4:
{
cout<<"in 4\n";
case 5: cout<<"in 5\n";
break;
}
}
break;
default:
{
cout<<"in deafult\n";
break;
}
}
return;
}
int main()
{
show(5);
return 0;
}
I used this sample of code and I could not figure out its flow.According to me it should match the default condition as the errorCause does not match anything,but its output is:
in 5
I don't understand why it is not going to default condition?
Here is my build environment details:
compiler:
g++ version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
System:
Ubuntu 14.04(64-bit)

You pass 5, why should the switch statement not go into 'case 5'?
To make it clear: Remove all these curly braces inside the switch-block, none of them is necessary. The re-align and format the code, then it should be clear.

case/default labels for a switch statement may appear anywhere within that switch statement, except within a nested switch statement.
A famous example of this usage is Duff's device for unrolling loops:
void copy(unsigned char *to, const unsigned char *from, size_t count)
{
size_t n;
if (!count)
return;
n = (count + 7) / 8;
switch (count % 8) {
case 0:
do {
*to++ = *from++;
case 1:
*to++ = *from++;
case 2:
*to++ = *from++;
case 3:
*to++ = *from++;
case 4:
*to++ = *from++;
case 5:
*to++ = *from++;
case 6:
*to++ = *from++;
case 7:
*to++ = *from++;
case 1:
} while (--n > 0);
}
}
(adapted from the original).
At first glance, that doesn't make any sense (and it is somewhat redundant if you allow the compiler to unroll loops for you), but it illustrates that case labels can be placed more or less where you like within the switch statement.

First, don't write code like that. <g>
Second, the reason that it gets to case 5: is simply that there's a case 5: inside the switch statement. It doesn't matter that it's nested inside two levels of curly braces; it's just a label for the code to jump to. It doesn't have to be at the outer level of the switch statement.

It's because actually the switch statement evaluation is "relaxed", so the braces do not matter there. Only case matters, but you can jump right into the middle of a scope by the case (or even to the middle of a loop, see Duff's device).

because the value you passed is 5 , which exactly matches with the switch case parameter.
case 5: cout<<"in 5\n";
break;
if you want to get the default statement then modify the main function as shown below :
int main()
{
show(6);
return 0;
}
hope this helps.

Related

Error: break statement not within loop or switch

I wrote this part of code and a series of error are being shown. The above mentioned error being the first. What is wrong in the code?
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
You can choose to omit the opening and closing braces for a switch statement only when you have only one case in your switch block as shown below:
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
}
But, if you have got multiple cases to deal with like in your case then you must enclose them inside a pair of opening and closing braces to create a code block for the switch statement as shown below:
void direction(char ch)
{
switch(ch)
{//opening brace for starting of statement block
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}//closing brace for closing of statement block
So you will have to either remove all the cases but one OR add the pair of braces to create statement block. In all other cases your code won't compile successfully.
You have forgotten the switch braces :
void direction(char ch)
{
switch(ch)
{
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}
}
switch statement requires braces block, where all labels including default one should be:
switch(ch)
{
case 'w': if(dirn!=3) dirn=1;
break;
case 'a': if(dirn!=2) dirn=4;
break;
case 's': if(dirn!=1) dirn=3;
break;
case 'd': if(dirn!=4) dirn=2;
break;
default:
break;
}
The statement after switch must be a compound statement to contain case, default and break. Break got a special meaning here, different from loops. If brace was omitted only next line after switch is part of its statement.

What are some interesting uses of 'switch' in C/C++? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
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++?
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
}
}
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;
// ...
}
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.
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.

Revising the syntax of Duff's device - Is this legal C/C++?

Only last night I encountered the curious Duff's device for the first time. I've been doing some reading on it, and I don't think it's that daunting to understand. What I am curious about is the strange syntax (from Wikipedia):
register short *to, *from;
register int count;
{
register int n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *to = *from++;
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);
}
}
I was reading the C++ standard definition of a switch statement (please let me know if that's outdated, I'm not familiar with Open-Std.org). So far as I can understand case statements are just simplified jump statements for use by the switch statement.
The switch itself completely ignores the nested do-while, and the loop ignores the case statements. Since the switch jumps inside of the loop, the loop is executed. The switch is there to cover the remainder (from the division by 8), and the loop handles the portion that is evenly divisible. This all makes sense.
My question then is why the awkward syntax? It occurs to me that the loop could be written such that all of the case statements are contained within, yes? I see nothing in the standard that prohibits this behavior, and it compiles correctly under GCC 4.7, so is the following considered legal?
register short *to, *from;
register int count;
{
register int n = (count + 7) / 8;
switch (count <= 0 ? 8 : count % 8)
{
do
{
case 0: *to = *from++;
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++;
default: ; // invalid count, suppress warning, etc.
} while(--n > 0);
}
}
To me this makes the intent of the code much clearer. Thanks for any feedback. ;)
Edit: As noted below, the original code was written for C and had implicit int for the count and n variables. Since I tagged it C++ I've modified that.
Edit 2: Modified the revised example code to account for invalid count values.
Looking at the C++11 Standard, the part of the code I think you're asking about would be allowed. Have you tried it?
The rule I see that's most applicable is:
Note: Usually, the substatement that is the subject of a switch is compound and case and default labels appear on the top-level statements contained within the (compound) substatement, but this is not required.
In fact, this means you could get rid of the braces around the do-while, and write
int n = (count + 7) / 8;
switch (count % 8) do
{
case 0: *to = *from++;
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);
However, this line is NOT valid C++:
register n = (count + 7) / 8;
C++ does not allow default-int, the type of a variable must be specified or inferred.
Oh here, fix the number of iterations without breaking formatting:
int n = 1 + count / 8;
switch (count % 8) do
{
*to = *from++;
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++;
case 0: ;
} while(--n > 0);
The code is certainly legal: There are no requirements at all about for blocks and/or loops. It is worth noting, though, that count == 0 isn't properly handled by the above loop. It is, however, properly handled by this one:
int count = atoi(ac == 1? "1": av[1]);
switch (count % 4)
{
case 0: while (0 < count) { std::cout << "0\n";
case 3: std::cout << "3\n";
case 2: std::cout << "2\n";
case 1: std::cout << "1\n";
count -= 4;
}
}
Putting the case 0 label inside the loop would also incorrectly execute the nested statements. Although I have seen Duff's device always using a do-while loop, it seems the above code is more natural to deal with the boundary condition.
Yes, it is legal. The labels of a switch statement is typically written at the same level as the switch statement. However, it is legal to write them inside compound statements, e.g. in the middle of a loop.
EDIT: There is no requirement that the body of the switch statement must start with a label, any code is legal. However, there is no way into it from the switch statement itself, so unless it is a loop, or a plain label, the code will be unreachable.
Another interesting thing with the swtich statement is that the braces are optional. However, in that case only one label is allowed:
switch (i)
case 5: printf("High five\n");

Is there any reason to use switch statement instead of strings of if and elseif? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Advantage of switch over if-else statement
Why the switch statement and not if-else?
The switch statement seems to be totally useless. Anything it can do can be done by if and else if link.
They probably even compile to the same code.
So why bother having it?
The break statements in switch drives me crazy and that label: format reminds me of goto.
This is for objective-c, c, C++. I am not sure if vb.net has switch statement, but even if it does I must have forgotten because I never use it.
They may well compile to the same code. But the intent is not necessarily to provide better compiled code so much as it is to provide better source code.
You can do while or for loops with if and goto as well but that doesn't make while and for useless. Would you rather have:
for (i = 0; i < 10; i++)
doSomethingWith (i);
or:
i = 0;
loop12:
if (! (i < 10))
goto skip12
doSomethingWith (i);
i++;
goto loop12
skip12:
if (color == WHITE)
{
}
else if (color == BLACK)
{
}
else if (color == GREY)
{
}
else if ((color == ORANGE) || (color == GREEN) || (color == BLUE))
{
}
else
{
}
vs
switch(color)
{
case WHITE:
break;
case BLACK:
break;
case GREY:
break;
case ORANGE:
case GREEN:
case BLUE:
break;
default:
break;
}
Isn't the latter more readable and requires lesser key strokes?
Apart from readability there's another unique use of switch-case: Duff's Device. This technique exploits the goto-ness of switch-case coupled with while.
void dsend(char* to, char* from, count) {
int n = (count + 7) / 8;
switch (count % 8) {
case 0: do {
*to = *from++;
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);
}
}
Performance of switch is same as if and else if blocks in the worst case. It may be better. This has been discussed before: Advantage of switch over if-else statement
Pros:
Switch offers a better way to write program than if
Switch works faster than if because during execution compiler generates jump table to decide which case is satisfied rather than checking which case is satisfied!
Cons:
case can only have int or char constants or an expression that evaluates to one of these!

c++ classes switch case

switch(choice)
{
case 1:
uinstance1.addNewProduct(data);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
uinstance1.listAllProducts(data);
break;
case 8:
break;
case 9:
break;
case 10:
//name,category,barcode,price,manufacturer,noinstock,soldpermonth,expirydate,discount
// Perishable(string,string,string,double,string,int,int);
Perishable item0("Ferrari","Automobile","9999",2999.99,"Popular",5,0);
data.addNew(item0);
break;
default:
cout<<"Wrong Choice "<<endl;
system("pause");
break;
}
}
Hi ,i have been thinking about this error for quite some time and cant seem to figure out the issue.
error C2361: initialization of 'item0' is skipped by 'default' label
: see declaration of 'item0'
Some help would be appreciated.
Thanks
The whole select block counts as one scope, if you decalare a variable in that scope you need to initialize it in every case statement (every possible execution path). You can avoid it by creating a additional scope in your case to avoid the problem (see the brackets):
switch(choice)
{
case 1:
uinstance1.addNewProduct(data);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
uinstance1.listAllProducts(data);
break;
case 8:
break;
case 9:
break;
case 10:
{
//name,category,barcode,price,manufacturer,noinstock,soldpermonth,expirydate,discount
// Perishable(string,string,string,double,string,int,int);
Perishable item0("Ferrari","Automobile","9999",2999.99,"Popular",5,0);
data.addNew(item0);
}
break;
default:
cout<<"Wrong Choice "<<endl;
system("pause");
break;
}
}
MSDN explains the error C2361 aptly:
The initialization of identifier can be skipped in a switch statement. You cannot jump past a declaration with an initializer unless the declaration is enclosed in a block. (Unless it is declared within a block, the variable is within scope until the end of the switch statement.)
Always pay attention to the error numbers they provide vital information about why the error.
You forgot the braces in one of the cases.
case 10:
{
^^^
Perishable item0;
data.addNew(item0);
break;
}
^^^
Your label is crossing initialization which is illegal. Pretty sure moving default to the top should fix it. You can also add code blocks { } around your relevant code. If you still have problems then move your object outside of the switch block.
You can't create variables inside case statements if you don't define explicity the scope.
There is another discussion about that: Variables inside case statement
case 10:
{ // <<-- This gives explicit scope for the stack variable and let's you get rid of the error
Perishable item0;
// ...
}
break;