开发者

Go to main() from user defined function

I have 3 functions: my_fun1(), my_fun2(), and my_fun3().

main() calls my_fun1() which calls my_fun2(), which in turn calls my_fun3().

Upon some pre-defined condition in my_fun3(), I would like my program to go directly back to the main() function at the line my_fun1() was called.

Is it possible to go directly from my_fun3() to main(), or do I have to add some conditions 开发者_开发百科to my_fun2() and my_fun1() to achieve this?


Well, there is a way to jump directly to another point in the code using longjmp/setjmp, but I'm not going to tell you how because it is a terrible idea. Just about as bad as it gets. So let's talk about good solutions :-).

The most obvious way is to use exceptions. Like this:

int my_fun3() {
    throw 1; // could be any type...
}
int my_fun2() {
    my_fun3();
}

int my_fun1() {
    my_fun2();
}

int main() {
    try {
        my_fun1();
    } catch(int n) { // catch the same type you threw...
    }
}

If you don't want to use exceptions, (which may be the case, some may argue that this would be an abuse of exceptions if the reason for going back to main is not "exceptional") the next most straightforward way is to make my_fun1, my_fun2, and my_fun3 return values meaning "done", let's say an int where a value less than 0 means "go back to main". Your call structure would look like this:

int my_fun3() {
   // ...
   if(some_condition) {
       return -1;
    }

    return 0;
}

int my_fun2() {
    // ...
    int r = my_fun3();
    if(r < 0) {
        return r;
    }
    // ...
    return 0;
}

int my_fun1() {
    // ...
    int r = my_fun2();
    if(r < 0) {
        return r;
    }
    // ...
    return 0;
}

int main() {
    my_fun1();
}


Yes, it's possible by throwing an exception and catching that in main. But please don't use exceptions as a general control flow mechanism, that's not what they're for.

There's also setjmp/longjmp, but code using them is very hard to follow.


Either return from all functions or throw and catch an exception (not recommended unless the reason to go up the stack is really error situation)


A clean approach without abusing exceptions would be

#define EXITCONDITION 42

void main ()
{
  ...
  myfunc1 ();
  ...
}

int myfunc1 ()
{
  ...
  if (myfunc2 () == EXITCONDITION) return EXITCONDITION;
  ...
}

int myfunc2 ()
{
  ...
  if (myfunc3 () == EXITCONDITION) return EXITCONDITION;
  ...
}

int myfunc3 ()
{
  ...
  if (somethingweirdhappens) retrun EXITCONDITION;
  ...
}


It seems you may be hinting at a goto which is bad.

Not seeing the structure of your program, you may consider a return boolean value (e.g. a flag) that is checked upon returning from function #3, which is checked in #2, which then returns, checked in #1, and then returns to main().


It's possible by throwing an exception, like larsmans said (though C++ only). It's also possible via setjmp()/longjmp(), which acts as a sort of cross-function goto statement.

But if this is really the design you want/need, then there's probably something wrong with your design. Having conditions in my_fun1 and my_fun2 may be the "correct" answer here, but it depends on what you're doing, of course. If you post a bit more information on why you may want/need this, we may be able to help you better.


Just put your first function call in a loop. That is one of the generally accepted programming methodologies anyway.

main
    while running
        do stuff

So you can do

bool running = false;

int main(int argc, char **argv)
{
    while(running)
        function1();
}

void function3()
{
    ...
    if(whatever)
    {
        running = true;
        return;
    }
    ...
}

If you need function1() and function2() to abort doing something based on this behavior, then your situation either is an error or is basically like an error, so throwing an exception would then be a better solution. Even if it's not an error, it's still basically the same type of control logic.

However, if this is the non-error control flow of your program, you might want to look at the structure more and figure out what is causing you to need to do it this way and try to avoid whatever logic is causing this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜