How can this switch statement be simplified? - c++

I have two switch statement on inside another.
Like this
switch(something)
{
case h:
switch(s)
{
case e:
break;
default:
}
break;
default:
}
Can i simplify it any way? Is there a way to use only one switch statement?
I thought of moving it to a different function but I'll need to pass a lot of variables.

It depends on what 'something' and 's' are.
Also, based on this switch statement. You could remove it completely and get the same results.

I don't think you need a break after the default, since there shouldn't be any skippable statements after it.
switch(something)
{
case h:
switch(s)
{
case e:
break;
default:
}
break;
default:
}

You could try indenting it more to make it more readable, but I don't see how you could do it with one switch

Without knowing what you are trying to accomplish with this logic we will not be able to siginificantly simplify this bit of code.
If the switch statements really are just checking for a single condition and then have default logic, this would probably be a little cleaner with if statements:
if (something == h)
{
if (s == e)
{
}
else
{
//default
}
}
else
{
//default
}

Maybe this is what you want?:
if((something == h) && (s == e))
{
// Do something
}

Related

Execute all cases in switch statement - specific issue

How to execute all cases in switch statement without duplicating existing in big "all-in-one" case ?
For e.g.
switch(obj.nObjType)
{
case eElephant:
...
break;
case eFoo:
...
break;
case eSeptember:
...
break;
default:
return;
}
I want force executing code for all 3 cases (eElephant, eFoo, eSeptember) like there is no break;, for example in case of nObjType = eAllTypes .
You can't just ignore a break. Rather, restructure your code.
switch(obj.nObjType) {
case eElephant:
pokeElephant();
break;
case eFoo:
barTheFoo();
break;
case eSeptember:
rememberSeptember();
break;
case eAllTypes:
pokeElephant();
barTheFoo();
rememberSeptember();
break;
default:
return;
}
Then use if statements:
if (obj.nObjType == eElephant || obj.nObjType == eAllTypes)
{
// Elephant code
}
if (obj.nObjType == eFoo || obj.nObjType == eAllTypes)
{
// Foo code
}
// etc.
This answer is how it should be done.
However:
I can see, it's hard to find as right solution without generating lots
of code lines. Thanks #TobiMcNamobi, but in my switch there is about
200 of cases, so creating a function for each case is not a good idea.
I think, the best can be (unfortunately) duplicating all cases in a
big one. Because, I suppose, if else is much less efficient then
switch statement ?
With this many cases (what on earth are you working on?) even extracting methods leaves you with 200 extra function calls in the body of your switch statement. This could get harder to maintain quickly.
In this case, I would do the following:
switch(enum_variable)
{
case e_all:
case e_1:
e_1_function();
if(enum_variable != e_all){break;} //**
case e_2:
e_2_function();
if(enum_variable != e_all){break;} //**
//...
default:
break;
}
The lines marked //** will break when not doing all cases. It is quick to implement (can be done with a search and replace of break; which speeds things up for you) and does what you want.
With that said, it's still a pretty terrible way of doing it, but exceptions do sometimes have to be made.
I do however recommend that you do not turn to this as a style to use in the future. You may find that you can do better by re-thinking the workflow of your project, as this will probably allow you to simplify and improve. Of course, we don't know what you are working on, so I can't offer more advice.
If you put your switch statement in a function, and make your obj have a list of flags rather than a flag, you can call the function with the switch statement for each flag in the list. Pseudo:
void dostuff(flag)
switch(flag) {
// ...
}
}
for (auto flag in obj.flags) {
dostuff(flag)
}

Nested redundant 'if' conditions

Is there a better (or cleaner) way to write the following code?
if(conditionX)
{
if(condition1)
{
// code X1
}
else if(condition2)
{
// code X2
}
}
else if(conditionY)
{
if(condition1)
{
// code Y1
}
else if(condition2)
{
// code Y2
}
}
I have a few more conditions, but I guess you get the point.
There are four approaches to this problem, none of which is universal:
Leave everything as is - There isn't much code duplication here. If computing condition1 and condition2 is tricky, compute them upfront and store them in bool variables
Make conditionX and conditionY produce a result that lets you unify condition1 and condition2 - This is not always possible, but in some situations you could prepare a variable that unifies the activities taken in the two branches, say, by using a function pointer or a lambda.
Put the processing logic into subclasses with virtual functions to eliminate conditional logic - This is possible only when your initial design missed an opportunity to subclass. Essentially, this approach pushes the decision on conditionX/conditionY into a place where a subclass is created, and then "reuses" that decision later on by calling a proper override of a virtual function in the interface.
Create a numeric combination representing all three conditions, and convert to switch - This trick unifies the conditionals, reducing the nesting.
Here is an example of the last approach:
int caseNumber = ((conditionX?1:0) << 3)
| ((conditionY?1:0) << 2)
| ((condition2?1:0) << 1)
| ((condition1?1:0) << 0);
switch (caseNumber) {
case 0x09:
case 0x0D:
case 0x0F: // code X1
break;
case 0x0A:
case 0x0E: // code X2
break;
case 0x05:
case 0x07: // code Y1
break;
case 0x06: // code Y2
break;
}
If your concern is with clean code in terms of viewing the source, my advice would be to segregate the blocks into their own sections, something like:
if (conditionX) processConditionX();
else if (conditionY) processConditionY();
and so on.
Then, in the sub-functions, you place the "meat":
void processConditionX (void) {
if(condition1) {
// code X1
} else if(condition2) {
// code X2
}
}
You can modify it to pass in and return parameters as necessary and I'd make the conditions and function names a little more descriptive, though I assume they're just examples here.
You can implement a state-machine instead:
#define COMBINATION(a,b,c,d) (((a)<<3)|((b)<<2)|((c)<<1)|((d)<<0))
switch (COMBINATION(conditionX,conditionY,condition1,condition2))
{
case COMBINATION(0,0,0,0): break;
case COMBINATION(0,0,0,1): break;
case COMBINATION(0,0,1,0): break;
case COMBINATION(0,0,1,1): break;
case COMBINATION(0,1,0,0): break;
case COMBINATION(0,1,0,1): CodeY2(); break;
case COMBINATION(0,1,1,0): CodeY1(); break;
case COMBINATION(0,1,1,1): CodeY1(); break;
case COMBINATION(1,0,0,0): break;
case COMBINATION(1,0,0,1): CodeX2(); break;
case COMBINATION(1,0,1,0): CodeX1(); break;
case COMBINATION(1,0,1,1): CodeX1(); break;
case COMBINATION(1,1,0,0): break;
case COMBINATION(1,1,0,1): CodeX2(); break;
case COMBINATION(1,1,1,0): CodeX1(); break;
case COMBINATION(1,1,1,1): CodeX1(); break;
}
This includes only one branch operation, so it is possibly a little more efficient (even though it also includes an additional runtime computation (at the switch line)).
As to being cleaner, I guess it's a matter of perspective, but the template above also gives you a convenient way to detect all unhandled branches within your code.
Please note that if any of the condition variables may have a value other than 1 or 0, then you should:
#define COMBINATION(a,b,c,d) (((a)?8:0)|((b)?4:0)|((c)?2:0)|((d)?1:0))
Update (attributed to #Jonathan Wakely in one of the comments below):
If you're using C++11, then you may replace the COMBINATION macro with a constexpr function:
constexpr int COMBINATION(bool a,bool b,bool c,bool d)
{
return ((int)a<<3) | ((int)b<<2) | ((int)c<<1) | ((int)d<<0);
}
I would provide the decision inside the first if as a parameter to a separated functions which then decides which code to execute, like:
if(conditionX)
{
Method1(Condition Parameters)
}
else if(conditionY)
{
Method1(Condition Parameters)
}
Another way would be to provide all needed info to a decision method (matrix), this method returns an integer which you use in a switch statement to decide which code to execute. In this way you separate the desicion logic which makes it readable and easy to unittest if needed:
DecisionMatrix(conditionX, conditionY, condition1, condition2)
{
// return a value according to the conditions for Example:
// CoditionX + Condition1 => return 1
// CoditionX + Condition2 => return 2
// CoditionY + Condition1 => return 3
// CoditionY + Condition2 => return 4
}
switch(DecisionMatrix)
{
case 1: //run code X1
break;
case 2: //run code X2
break;
case 3: //run code Y1
break;
case 4: //run code Y2
break;
}
The best way here would be to use polymorphism (Only if the chunks of code are huge)
If they are small code snippets, creating classes would obviously be an overkill.
Therefore, if there is similarity in all codes, I'd suggest a seemingly easy but really difficult task.
Try to parametrize them as much as you can.
Create a function that takes those and call them in the conditions
Now the code would be in function blocks and "cleaner"
It is always difficult to create simple things.
if (conditionX) {
method(parameterX);
else if (conditionY) {
method(parameterY);
}
where
void method(ParameterType e) {
if (condition 1) {
// Code in terms of parameter e
} else if (condition2) {
// Code in terms of parameter e
}
}
The condition that you can parametrize should be kept outside.
Hope this helps.
I think this way can be another way for solving your code.
enum ConditionParentType
{
CONDITION_NONE = 0,
CONDITION_X,
CONDITION_Y,
};
enum ConditionChildType
{
CONDITION_0 = 0,
CONDITION_1,
CONDITION_2,
};
class ConditionHandler
{
public:
explicit ConditionHandler(ConditionParentType p_type, ConditionChildType c_type)
: p_type_(p_type), c_type_(c_type) {};
void DoAction()
{
if(child_type == CONDITION_1)
{
}
else if(child_type == CONDITION_2)
{
}
else
{
//error
}
}
private:
const ConditionParentType p_type_;
const ConditionChildType c_type_;
};
int main(int argc, char *argv[])
{
ConditionParentType parent_type = GetParentType();
ConditionChildType child_type = GetChildType();
ConditionHandler handler(parent_type, child_type);
handler.DoAction();
getchar();
return 0;
}
If the combination of conditions means something then I'd write a set simple methods that return boolean values. You would end up with something like:
if (first-condition(conditionX, condition1)) {
// code X1
} else if (first-condition(conditionX, condition2)) {
// code X2
} else if (third-condition(conditionY, condition1)) {
// code Y1
} else if (fourth-condition(conditionY, condition2)) {
// code Y2
}
The names of the methods describe the conditions. Don't worry that the methods are only called once (the compiler will probably in-line them anyway), the important bit it that your code then becomes self documenting.
I'm quite surprised by the other suggested answers, which are mostly wrong if:
The two repeated conditions condition1 or condition2 are complex, in which case DRY comes into play, or
Any of the four conditions have side effects, or
Any of the conditions are slow (for example, find the minimum of a large array, or read a file), or
A boolean short-circuit is needed, as in: if (p == 0) {...} else if (p->foo == 42) {...}.
If none of these hold, as is the case 99.42% of the time, then leave the code as it is. Or, as a minor variation, change it so the nesting (that is, indentation) is only one level, not two.
Otherwise, you will need to use temporary variables as follows
const bool tstX = (conditionX);
const bool tstY = tstX || (conditionY);
const bool tst1 = tstY && (condition1);
const bool tst2 = tstY && !tst1 && (condition2);
the original code doesn't look to bad. Depending on the specific case it may or may not be more readable to do something like:
if(conditionX and condition1) {
// code X1
}
else if(conditionX and condition2) {
// code X2
}
else if(conditionY and condition1) {
// code Y1
}
else if(conditionY and condition2)
// code Y2
}

Control structures inside switch statements

why the code inside the if block executed any way?
switch(v)
{
case a:
break;
...
if(condition)
{
case f:
...
break;
case g:
...
break;
}
...
case z:
...
break;
default:
}
The C++ compiler uses a lookup table or direct branches to the case-statements. Ignoring your the if-statement. Due to the break it is also not reached from case a.
Long answer short you cannot 'turn off' case-statements using this method.
Instead you'd need something like this:
switch(v) {
case a :
break;
//...
case f :
if(condition) {
//...
}
break;
case g :
if(condition) {
//...
}
break
//...
case z :
break;
}
A case label, as the name implies, is an actual label and works very similar to a goto label: the execution thread just jumps to it. It does not matter what structure it is in, unless that structure is another, nested switch statement.
It works the same way as this:
if (v == f)
goto f_label;
if (condition) {
f_label:
// ...
}
The execution thread will jump to the f_label: label regardless of whether condition is true or not. switch labels work the same way.
The case clauses for a switch are quite flexible and you can do some hacks for them. I have seen some people use switch to break out of nested for loops for instance. Still in the example above if v is f or g the switch will just skip the if statement and the code in the case will be executed right after switch.
When program is compiling switch builds some table to jump from one case to another. This jumps somehow ignoring other conditional operations. BTW according to such behavior switch is faster than long if-else blocks.
I think the best answer to how is( inspired from the answer of Nikos C.):
switch(v)
{
case a:
break;
case z:
...
break;
default:
if(condition)
{
switch(v)
{
case f:
...
break;
case g:
...
break;
default:
//former default
}
}
else
//former default
}
Switch jumps to the matched case ignoring all statements in between. You have two ways to accomplish what you intend to do (depending upon the number of cases you have to implement):
Method 1 for more number of cases under the if conditional
if(condition) {
switch(v) {
case f :
....
break;
//...
case g :
....
break;
//...
case z :
break;
}
switch(v) {
case a :
....
break;
//...
}
Method 2 for less cases under the if conditional
switch(v) {
case a :
break;
//...
case f :
if(condition) {
//...
}
break;
case g :
if(condition) {
//...
}
break
//...
case z :
break;
}

coldfusion calling another case within a switch

I have a switch like thus (written in cfscript):
switch (something) {
case "stuff":
if(this eq that){
writeDump("hello");
} else { /* do other? */ }
break;
case "other":
//do something else
break;
}
In my else, I want to be able to tell it that I want the "other" case to be invoked. Is this possible? (I seem to remember doing this in other languages.)
There is no GOTO construct in CF, no. And that's pretty much what you're asking for.
If your switch is really as simple as you indicate, and you want to fall through to the NEXT case when the condition is false, what you could do is to have the break statement in the true branch of the if clause, and have no break statement in the false branch. Then when the false branch runs, processing will not exit the case when it's done; it'll fall through to the next case.
As Adam explained, it is possible, here is some code to show how:
something = "stuff";
test = "more stuff";
switch (something) {
case "stuff":
if(test eq "more stuff"){
writeOutput("<p>Something</p>");
break;
}
case "other":
writeOutput("<p>something Else</p>");
break;
}
Change the values of 'something' and 'test' to see different results. When using a switch in cfscript, if there is no 'break' then ColdFusion will continue processing the cases until it hits one.
As far as I'm aware that's not possible. You'll need to use an if else statement, or nested is/else, instead of the switch.
something = "other";
if (something eq "stuff" and 1 eq 2) {
writeDump("hello");
} else if (something eq "other") {
writedump("other");
}

Does case-switch work like this?

I came across a case-switch piece of code today and was a bit surprised to see how it worked. The code was:
switch (blah)
{
case a:
break;
case b:
break;
case c:
case d:
case e:
{
/* code here */
}
break;
default :
return;
}
To my surprise in the scenario where the variable was c, the path went inside the "code here" segment. I agree there is no break at the end of the c part of the case switch, but I would have imagined it to go through default instead. When you land at a case blah: line, doesn't it check if your current value matches the particular case and only then let you in the specific segment? Otherwise what's the point of having a case?
This is called case fall-through, and is a desirable behavior. It allows you to share code between cases.
An example of how to use case fall-through behavior:
switch(blah)
{
case a:
function1();
case b:
function2();
case c:
function3();
break;
default:
break;
}
If you enter the switch when blah == a, then you will execute function1(), function2(), and function3().
If you don't want to have this behavior, you can opt out of it by including break statements.
switch(blah)
{
case a:
function1();
break;
case b:
function2();
break;
case c:
function3();
break;
default:
break;
}
The way a switch statement works is that it will (more or less) execute a goto to jump to your case label, and keep running from that point. When the execution hits a break, it leaves the switch block.
That is the correct behavior, and it is referred to as "falling through". This lets you have multiple cases handled by the same code. In advanced situations, you may want to perform some code in one case, then fall through to another case.
Contrived example:
switch(command)
{
case CMD_SAVEAS:
{
this->PromptForFilename();
} // DO NOT BREAK, we still want to save
case CMD_SAVE:
{
this->Save();
} break;
case CMD_CLOSE:
{
this->Close();
} break;
default:
break;
}
This is called a fall-through.
It is exactly doing what you are seeing: several cases is going to execute same piece of code.
It is also convenient in doing extra processing for certain case, and some shared logic:
// psuedo code:
void stopServer() {
switch (serverStatus)
case STARTING:
{
extraCleanUpForStartingServer();
// fall-thru
}
case STARTED:
{
deallocateResources();
serverStatus = STOPPED;
break;
}
case STOPPING:
case STOPPED:
default:
// ignored
break;
}
This is a typical use of fall-through in switch-case. In case of STARTING and STARTED, we need to do deallocateResources and change the status to STOPPED, but STARTING need some extra cleanup. By the above way, you can clearly present the 'common logic' plus extra logic in STARTING.
STOPPED, STOPPING and default are similar, all of them fall thru to default logic (which is ignoring).
It is not always a good way to code like this but if it is well used it can present the logic better.
Luckily for us, C++ doesn't depend on your imagination :-)
Think of the switch labels as "goto" labels, and the switch(blah) simply "goes to" the corresponding label, and then the code just flows from there.
Actually the switch statement works the way you observed. It is designed so that you can combine several cases together until a break is encountered and it acts something like a sieve.
Here is a real-world example from one of my projects:
struct keystore_entry *new_keystore(p_rsd_t rsd, enum keystore_entry_type type, const void *value, size_t size) {
struct keystore_entry *e;
e = rsd_malloc(rsd, sizeof(struct keystore_entry));
if ( !e )
return NULL;
e->type = type;
switch (e->type) {
case KE_DOUBLE:
memcpy(&e->dblval, value, sizeof(double));
break;
case KE_INTEGER:
memcpy(&e->intval, value, sizeof(int));
break;
/* NOTICE HERE */
case KE_STRING:
if ( size == 0 ) {
/* calculate the size if it's zero */
size = strlen((const char *)value);
}
case KE_VOIDPTR:
e->ptr = rsd_malloc(rsd, size);
e->size = size;
memcpy(e->ptr, value, size);
break;
/* TO HERE */
default:
return NULL;
}
return e;
}
The code for KE_STRING and KE_VOIDPTR cases is identical except for the calculation of size in case of string.