C++ Try Catch inside loop - c++

I have this C++ program with the following general structure
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
//condition B == false (supposed to leave 2nd loop and go back to first loop)
I want it to get out of 2nd loop when there's an exception and go back to 1st loop until condition B is tue again. As described above it doesn't work as I expect. What seems to be happening is that code gets stuck in catch and never leaves it.
How can I arrange it to make it work as I need?
Note: condition A is never false.

add the break keyword to the catch
Also notice that you have b == false;
That is checking that b is equal to false, not setting b = false.

bool flag1 = true, flag2 = true;
while (flag1)
{
// some work so that flag2 == true
while (flag2)
{
try
{
}
catch (...) // any exception happens
{
break;
}
}
}

1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
{
//condition B == false (supposed to leave 2nd loop and go back to first loop)
break ;
}
Notice: Please do not use, even in examples, things like condition A == true. It is better to use while (condition A).

You can call break within the catch block to escape the second loop:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
while (B) {
try {
B = doSomethingElseThatMayThrow();
} catch (...) {
break;
}
}
}
}
Alternatively, you could place the second loop inside the try block:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
try {
while (B) {
B = doSomethingElseThatMayThrow();
}
} catch (...) {}
}
}

Related

No return evaluation in nested if

After watching carefully the following code I can't see why the compiler is warning me with "warning: control reaches end of non-void function".
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
}
else
{
return false;
}
}
I can't see where is the problem, the else statement should care for returning false in every case which the first if is not true.
Trace the code path when regIOobject::read() is true, but either of permeabilityModelPtr_->read(subDict("permeability")) or magnetizationModelPtr_->read(subDict("magnetization")) is false. In that case, you enter the top if block (excluding the possibility of entering its attached else block), but then fail to enter the nested if block:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
else
{
// First if was true, so we don't go here...
return false;
}
// End of function reached, where is the return???
}
The minimalist fix is to just remove the else { } wrapping, so any fallthrough ends up at return false;:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
// Oh, but we hit return false; so we're fine
return false;
}
Alternatively, avoid specifically mentioning true or false at all, since your function is logically just a result of anding three conditions together:
bool Foam::solidMagnetostaticModel::read()
{
// No need to use ifs or explicit references to true/false at all
return regIOobject::read() &&
permeabilityModelPtr_->read(subDict("permeability")) &&
magnetizationModelPtr_->read(subDict("magnetization"));
}
The nested if is the problem.
When that branch is not taken, there is no other paths to take
the else statement should care for returning false in every case which the first if is not true.
Correct, but what if the first if condition is true, but the second if condition is not?
That is: What if regIOobject::read() returns true, but permeabilityModelPtr_->read(subDict("permeability")) returns false?
Then the flow of control enters the first if block, does not return, but does not enter the else block (because the first condition was true), so it just falls off the end of the function without hitting a return statement.
If you want the else { return false; } part to apply to either condition, you could just naively copy/paste it:
if (COND1) {
if (COND2) {
return true;
} else {
return false;
}
} else {
return false;
}
But that's quite a bit of code duplication. A better solution is to replace the nested if by a single condition:
if (COND1 && COND2) {
return true;
} else {
return false;
}
There's still some duplication: Both branches consist of a return statement followed by some expression.
We can factor out the common parts (return) and push the condition into the expression:
return COND1 && COND2 ? true : false;
But ? true : false is redundant: If the condition is true, evaluate to true, else evaluate to false? Well, that's just what the condition itself does:
return COND1 && COND2;
Or with your concrete expressions:
return regIOobject::read()
&& permeabilityModelPtr_->read(subDict("permeability"))
&& magnetizationModelPtr_->read(subDict("magnetization"));

exiting from nested loop without goto

how can i exit from nested while() or for() without goto?
for example if i use three loops like below in a function:
void myfun(){
for (;;)
{
while( true )
{
for (;;)
{
//what is the exit code of all loop() from here?
}
}
}
}
using break; only can exit from one loop,
but how can i exit all loops ?
the loops can be limited by counter or unlimited.
I personally would rewrite the code so that you don't have a nested loop in the first place. Something like this:
bool myFun2
{
for (;;)
{
if(something) return true;
}
// If the loop isn't "forever", return false here?
}
bool myFun1()
{
while( true )
{
if (myFun2()) return true;
}
// return false here if needed.
}
void myfun()
{
for (;;)
{
if(myFun1()) break;
}
}
This becomes much easier to follow than trying to figure out which conditions some exitLoop variable gets set, for example.
You can't, you need another break at while context or change yours loops usign a variable as a exit flag:
bool exit = false;
for (;;){
while (!exit){
for (;;){
exit = true;
break;
}
}
if (exit) break;
}
An so on for as many loop do you have in your code
If you want to jump out of the function that is leave the function then you should use return. However if you want to just jump off the nested loops & not out of the function then you can throw an exception. This method will help you from breaking the code into several functions as some have done. However exceptions are meant for library designers & we should avoid using them too much. Personally speaking using goto is the best thing in this case but as you asked against it, hence I'm saying so. Well then your code will look like this :-
void myfun()
{
try
{
for (;;)
{
while( true )
{
for (;;)
{
if (/*some condition*/)
throw false;
}
}
}
}
catch (bool)
{
cout<<"caught";
}
// do stuffs if your code is successful that is you don't break out
}

Run cursor through vector while checking its bounds

I have a cursor that has its "position" determined by another part of the code. My intention is to have this cursor check through the next and previous object of a vector and check for a condition. If it's valid, the cursor takes this object's position.
Here's some sample code of my idea:
class A
{
bool valid;
public:
A(bool v) {valid=b;}
bool IsValid() {return valid;}
};
void CheckNearbyValidity()
{
/*if the object to the right is valid, update position to this object*/
if(exampleVector.at(cursor-1).IsValid())
{
/*do stuff*/
cursor = (cursor-1);
}
/*if the object to the right isnt valid, try the same thing to the left*/
else if(exampleVector.at(position+1).IsValid())
{
/*do stuff*/
cursor = (cursor+1);
}
/*leave if none are valid*/
}
The problem I encounter here is that if the cursor is at the start or end of the vector, checking the if conditions will cause it to throw an out of range exception.
My solution was to check if the new cursor position was valid before querying the vector:
void CheckNearbyValidity()
{
/*if the object to the right is valid, update position to this object*/
if(cursor-1 >= 0)
{
if(exampleVector.at(cursor).IsValid())
{
/*do stuff*/
cursor = (cursor-1);
}
}
/*new position makes the next condition always true and returns cursor to the same position*/
if(cursor-1 < exampleVector.size())
{
if(exampleVector.at(cursor+1).IsValid())
{
/*do stuff*/
cursor = (cursor+1);
}
}
/*leave if none are valid*/
}
The new problem was that since I could no longe use "else", both conditions would be valid and the cursor would remain where it started.
My workaround to this problem was to surround the function in a while loop, and break when necessary:
void CheckNearbyValidity()
{
while(true)
{
if(cursor-1 >= 0)
{
if(exampleVector.at(cursor-1).IsValid())
{
/*do stuff*/
position = (cursor-1);
break;
}
}
if(cursor-1 >= 0)
{
if(exampleVector.at(cursor+1).IsValid())
{
/*do stuff*/
position = (cursor+1);
break;
}
}
break;
}
}
My question is, is the "single" while loop approach a bad idea? Is there a better way to manipulate this cursor?
You should harness the power of &&:
if (cursor-1 >= 0 &&
exampleVector.at(cursor-1).IsValid())
{
/*do stuff*/
position = (cursor-1);
}
else if (cursor+1 < exampleVector.size() &&
exampleVector.at(cursor+1).IsValid())
{
/*do stuff*/
position = (cursor+1);
}
This allows you to connect the two statements together as an if-else as you had originally, only with the additional validation step checking cursor against the vector bounds.
The && performs short-circuit evaluation. If cursor-1 >= 0 evaluates to false, then the code skips evaluating exampleVector.at(cursor-1).IsValid() and jumps immediately to evaluating the else clause.
Likewise, in the else if clause, if cursor+1 < exampleVector.size() evaluates to false, the && short-circuits and the code skips evaluating exampleVector.at(cursor+1).IsValid(), again making it safe.

How can I get which part of an if expression is true?

Assume I have code like:
if(condition1 || condition2 || condition 3 || condition4)
{
// this inner part will be executed if one of the conditions is true.
// Now I want to know by which condition this part is executed.
}
I'm sure there are better ways to do this, here's one:
int i = 0;
auto check = [&i](bool b)->bool
{
if (!b) ++i;
return b;
};
if (check(false) || // 0
check(false) || // 1
check(true) || // 2
check(false)) // 3
{
std::cout << i; // prints 2
}
|| is short circuit evaluation, so you can have code like this :
if(condition1 || condition2 || condition 3 || condition4)
{
if (condition1 )
{
//it must be condition1 which make the overall result true
}
else if (condition2)
{
//it must be condition2 which make the overall result true
}
else if (condition3)
{
//it must be condition3 which make the overall result true
}
else
{
//it must be condition4 which make the overall result true
}
// this inner part will executed if one of the condition true. Now I want to know by which condition this part is executed.
}
else
{
}
If the conditions are independent of each other, you need to check them separately, or, if they belong to one variable, you can use a switch statement
bool c1;
bool c2
if ( c1 || c2 )
{
// these need to be checked separately
}
int i; // i should be checked for multiple conditions. Here switch is most appropriate
switch (i)
{
case 0: // stuff
break;
case 1: // other stuff
break;
default: // default stuff if none of the conditions above is true
}
Without a switch you can use only or and if statements:
if(condition1 || condition2 || condition 3 || condition4) {
// this inner part will executed if one of the condition true.
//Now I want to know by which condition this part is executed.
if ( condition1 || condition2 ) {
if ( condition1 )
printf("Loop caused by 1");
else
printf("Loop caused by 2");
else
if ( condition3)
printf("Loop caused by 3");
else
printf("Loop caused by 4");
}
I'm not sure that this is the most efficient thing you've ever seen, but it will identify which of the four conditions caused entry into the if ... block.
If you need to know for programmatic reasons, i.e. run different code depending on which condition is true, you could do something like this
if (condition1)
{
...
}
else if (condition2)
{
...
}
else if (condition3)
{
...
}
else if (condition4)
{
...
}
else
{
...
}
If you only want to know for debugging reasons, just do a printout.
What about the comma operator?
By using that logical operators follow the short circuit evaluation method, the following works fine:
int w = 0; /* w <= 0 will mean "no one is true" */
if ( (w++, cond1) || (w++, cond2) || ... || (w++, condN) )
printf("The first condition that was true has number: %d.\n", w);

TCL: loops How to get out of inner most loop to outside?

In the below code once I hit check_access as 0 how do I preserve the value and hit the
if condition below ($check_root && $check_access) . Break will only terminate the inner loop. But the other loops will continue as per me.
} else {
set check_access 0
break
}
}
}
if {$check_root && $check_access} {
set result 1
} else {
set result 0
}
The break and continue operations only go out one level of looping. If you need more than that, consider refactoring so that you can just return. Alternatively, try a custom exception in Tcl 8.6:
try {
foreach a $longList1 {
foreach b $longList2 {
if {[someCondition $a $b]} {
# Custom non-error exception
return -level 0 -code 123
}
}
}
} on 123 {} {
# Do nothing; we're out of the loop
}
break jumps to the end of the innermost loop only, and Tcl has no goto. But return, unless it's inside a catch or similar, exits a procedure which is like jumping to the end of it. So if you make the outermost loop the last command of the procedure (if your code is top-level, you have to put it in a procedure first to be able to use return), you can use return as a multi-break. Just move the commands after the loop out of the procedure and into the caller's code:
proc callMe {} {
foreach ... {
foreach ... {
if ... {
return
}
}
}
# move this code from here...
}
callMe
# ...to here
Another way is to put in extra tests:
set done 0
foreach ... {
foreach ... {
foreach ... {
if ... {
set done 1
break
}
}
if {$done} {break}
}
if {$done} {break}
}