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
}
Related
I have several functions that try and evaluate some data. Each function returns a 1 if it can successfully evaluate the data or 0 if it can not. The functions are called one after the other but execution should stop if one returns a value of 1.
Example functions look like so:
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
... more functions ...
How would be the clearest way to organise this flow? I know I can use if statements as such:
void doSomething(void)
{
if (function1(data))
{
return;
}
if (function2(data))
{
return;
}
... more if's ...
}
But this seems long winded and has a huge number of if's that need typing. Another choice I thought of is to call the next function from the return 0 of the function like so
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function2(data);
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function3(data);
}
... more functions ...
Making calling cleaner because you only need to call function1() to evaluate as far as you need to but seems to make the code harder to maintain. If another check need to be inserted into the middle of the flow, or the order of the calls changes, then all of the functions after the new one will need to be changed to account for it.
Am I missing some smart clear c++ way of achieving this kind of program flow or is one of these methods best. I am leaning towards the if method at the moment but I feel like I am missing something.
void doSomething() {
function1(data) || function2(data) /* || ... more function calls ... */;
}
Logical-or || operator happens to have the properties you need - evaluated left to right and stops as soon as one operand is true.
I think you can make a vector of lambdas where each lambdas contains specific process on how you evaluate your data. Something like this.
std::vector<std::function<bool(std::string&)> listCheckers;
listCheckers.push_back([](std::string& p_data) -> bool { return function1(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function2(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function3(p_data); });
//...and so on...
//-----------------------------
std::string theData = "Hello I'm a Data";
//evaluate all data
bool bSuccess = false;
for(fnChecker : listCheckers){
if(fnChecker(theData)) {
bSuccess = true;
break;
}
}
if(bSuccess ) { cout << "A function has evaluated the data successfully." << endl; }
You can modify the list however you like at runtime by: external objects, config settings from file, etc...
This might be a non-sense question, but i'm kind of stuck so I was wondering if someone can help. I have the following code:
bool while_condition=false;
do{
if(/*condition*/){
//code
}
else if(/*condition*/){
//code
}
else if(/*condition*/){
//code
}
...//some more else if
else{
//code
}
check_for_do_while_loop(while_condition, /*other parameters*/);
}while(while_condition);
the various if and else if exclude with each other but each have other if inside; if a certain condition is met (which can't be specified in a single if statement), then the code return a value and the do while loop is ended. But if, after entering a single else if, the conditions inside aren't met the code exit without actually doing nothing, and the while loop restart the whole.
I want the program to remember where he entered and avoid that part of the code, i.e. to avoid that specific else if he entered without any result, so he can try entering another else if. I thought about associating a boolean to the statements but I'm not quite sure on how to do it. Is there a way which allows me not to modify the code structure too much?
To give an idea of one way of approaching this that avoid loads of variables, here is an outline of how you might data-drive a solution.
class TestItem
{
public:
typedef bool (*TestFuncDef)(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr);
TestItem(TestFuncDef test_fn_parm)
{
test_fn = test_fn_parm;
already_invoked = false;
}
bool Invoke(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr)
{
already_invoked = true;
return test_fn(state_to_test, result_ptr);
}
bool AlreadyInvoked() const {return already_invoked; }
private:
TestFuncDef test_fn;
bool already_invoked;
};
std::shared_ptr<result_type> RunTest(std::list<TestItem>& test_item_list, state_type& state_to_test)
{
for(;;) {
bool made_a_test = false;
for (TestItem& item : test_item_list) {
std::shared_ptr<result_type> result_ptr;
if (!item.AlreadyInvoked()) {
made_a_test = true;
if (item.Invoke(state_to_test, result_ptr)) {
return result_ptr;
}
else
continue;
}
}
if (!made_a_test)
throw appropriate_exception("No conditions were matched");
}
}
This is not supposed to be a full solution to your problem but suggests another way of approaching it.
The important step not documented here is to build up the std::list of TestItems to be passed to RunTest. Code to do so might look like this
std::list<TestItem> test_item_list;
test_item_list.push_back(TestItem(ConditionFn1));
test_item_list.push_back(TestItem(ConditionFn2));
The definition of ConditionFn1 might look something like
bool ConditionFn1(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr)
{
// Do some work
if (....)
return false;
else {
result_ptr.reset(new result_type(some_args));
return true;
}
}
I've come across a situation where I have a bunch of "systems" that need to be initialized in sequence, with the next system only being initialized if all of the proceeding systems initialized successfully.
This has led me to a whole slew of nested if - else statements. Here's some pseudo-code for visualization.
bool mainInit () {
if (!system1Init ()) {
reportError (); // some error reporting function
}
else {
if (!system2Init ()) {
reportError ();
}
else {
if (!system3Init ()) {
// ... and so on
I find that this starts to look like a mess when you get even a handful of levels to it.
Now I thought of using a switch statement instead, starting at the first case and falling through to the other cases on success, only breaking if there's an error.
bool mainInit () {
switch (1) {
case 1:
if (!system1Init ()) {
reportError ();
break;
}
case 2:
if (!system2Init ())
reportError ();
break;
}
// ....
}
Now, I like this a lot better. I find it much easier to read, especially with some decent comments, but I'm fairly new to programming.
So, my question is: Seeing how this is not how switch statements are traditionally used(at least from what I've seen), is something like this acceptable, or would this be considered bad form?
Being new to programming, I'm trying not to develop too many bad habits that might frustrate and make things more difficult for other programmers down the road.
I did a search, but most of what I found had to do with replacing chains of if - else if statements, not replacing nested ones.
Reference all of the systems in an array, for example an std::vector<mySystem*>, and loop over them sequentially, breaking off on the first fail. This way your entire code is reduced to less than 5 lines of code, even for 500+ systems.
The suggested switch hack is an evil example of XY problem solving: your real problem is that you don't have the array of systems, and are using named variables, thus eliminating all options to more flexibly use all systems, like in a loop.
Assuming that all your system#Init() calls are known at compile time, you can very easily put them in a table and then iterate over that table.
typedef (*system_init)(void);
system_init initialization_functions[] =
{
system1Init,
system2Init,
system3Init,
...
systemNInit
};
bool mainInit()
{
for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
{
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
}
return true;
}
However, your existing code looks incorrect since the first mainInit() only calls system1Init() and then exits. Probably not what you wanted in the first place.
if(!system1Init())
{
ReportError();
return false;
}
// if you add an else, the system2Init() does not get called
// even if system1Init() succeeds
if(!system2Init())
{
ReportError();
return false;
}
[...]
return true;
Would the switch answer your problem? Not as it was written. That is, if you wanted to call the mainInit() function with a counter, it could be useful. Drupal uses that mechanism:
bool mainInit(int idx)
{
bool r(true);
switch(idx)
{
case 1:
r = system1Init();
break;
case 2:
r = system2Init();
break;
[...]
}
if(!r)
{
ReportError();
}
return r
}
Note that the table mechanism works the same way as the switch. As long as all the code is found in the systemNInit() functions (and it should be), the switch does not add anything, so you could do something like this too:
bool mainInit(int idx)
{
if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
{
throw std::range_error("index out of bounds");
}
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
return true;
}
Calling the mainInit() with an index can be helpful in case you want to "de-initialize" properly:
int main()
{
for(size_t idx(0); idx < ...; ++idx)
{
if(!mainInit(idx))
{
while(idx > 0)
{
--idx;
mainDeinit(idx);
}
exit(1);
}
}
...app do something here...
}
Use custom exceptions with clear error messages and add a try-catch-report-die around the code in main(). Exceptions are there to specifically make your case look good by making "bad path" implicit.
void initX() { ...; throw std::invalid_argument_exception("..."); }
int main() {
try {
init1(); init2(); ... run();
return 0;
} catch (std::exception const& e) {
log(e.what()); exit 42;
}
}
I'd do it this way:
bool mainInit () {
if (!system1Init ()) {
return(false);
}
if (!system2Init ()) {
return(false);
}
if (!system3Init ()) {
return(false);
}
//...
return(true);
}
//...
if(!mainInit()) {
reportError();
}
If I desire to run a piece of code in a function, only from the second invocation of the function onwards,
Questions:
Is there something wrong to do that?
How can I possibly achieve this ? Is using a static variable to do this a good idea ?
There's two answers to this question, depending on whether you have to deal with multi-threaded serialization or not.
No threading:
void doSomething() {
static bool firstTime = true;
if (firstTime) {
// do code specific to first pass
firstTime = false;
} else {
// do code specific to 2nd+ pass
}
// do any code that is common
}
With threading:
I'll write the generic boilerplate, but this code is system specific (requiring some variant of an atomic compareAndSet).
void doSomethingThreadSafe() {
static volatile atomic<int> passState = 0;
do {
if ( passState == 2 ) {
//perform pass 2+ code
break;
} else
if ( passState.compareAndSet(0,1) ) { // if passState==0 set passState=1 return true else return false
//perform pass 1 initialization code
passState = 2;
break;
} else {
//loser in setup collision, delay (wait for init code to finish) then retry
sleep(1);
}
} while(1);
//perform code common to all passes
}
Multi-threading will be a problem. To prevent this, if required, you'll probably need something like a mutex.
Like this:
void someFunction()
{
static bool firstRun = true;
if (!firstRun)
{
// code to execute from the second time onwards
}
else
{
firstRun = false;
}
// other code
}
Add a global counter.
eg:-
static int counter = 0;
public void testFunc(){
if(counter==1){
........
<Execute the functionality>
........
}
counter++;
}
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 (...) {}
}
}