如何强制破坏方法的执行

时间:2013-11-26 09:25:50

标签: c++ c exception exit break

我有一个方法:

void doSomethingMain(char* s)
{
   doSomethingElse(s);
   doMoreStuff(s);
}

方法doSomethingElse()就像:

void doSomethingElse(char* s)
{
   anotherMethod(s);
   moreStuff(s);
}

其中anotherMethod()moreStuff()调用其他方法,这些方法可能会以非常递归的方式返回doSomethingElse()moreStuff()或其他方法,但没有一个调用主doSomethingMain()方法。这是一个有限的递归,它将在成功使用s时结束。方法是无效的,如果不付出巨大的努力,我们就无法改变它。

所有这些方法都在使用参数s,他们正在检查s中的错误。我想要发生的是以下内容:当调用堆栈中的某个方法遇到输入参数(s)中的错误时,我想立即中止执行发现错误的函数,并跳转返回doMoreStuff()中的doSomethingMain()

显然,C++方法的直接解决方案之一是throwcatch()对,而C方法是setjmp方法和longjmp对...但是我们的单元测试框架不喜欢throw ... catch对(它将它们解释为错误),我想避免{{1方法,所以这是问题:

我们还有什么其他选择来中断方法中应用程序的执行流程并继续在特定位置(方法之后的下一个语句)?

6 个答案:

答案 0 :(得分:1)

您可以更改方法以返回bool。如果解析成功,则在递归结束时,返回将传递给调用函数的true。如果在任何时候解析都证明不成功,则返回false,并在调用函数测试中返回整个递归的返回值。

  

但是我们的单元测试框架不喜欢throw ... catch对(它将它们解释为错误,并且在它们之后不再执行测试)

更改测试单元框架。

答案 1 :(得分:1)

返回一个错误代码,该代码已被选中。例如,您可以在出错时返回false(请参阅C中的<stdbool.h>),并在成功时返回true。如果函数也返回false, then return (possible with false`。

使用setjmp / longjmp并非我推荐的内容,即使是这样的情况。

答案 2 :(得分:1)

这是完全 longjmp()的用途,抱歉。但是,您理论上可以使所有函数返回错误代码,然后应检查对这些函数的所有调用以获取返回代码。遇到错误时,任何调用函数都应该立即返回(使用相同的错误代码)。因此,一个错误将导致立即返回第一个调用者(通过调用堆栈上的所有其他帧)。

答案 3 :(得分:1)

  

但是我们的单元测试框架不喜欢throw ... catch   对(它将它们解释为错误,并且不再执行任何测试   在他们之后)

这个怎么样:

try
{
  doMoreStuff(s);
}
catch (...)
{
  // hmmm I won't rethrow because my unit testing framework doesn't like it
}

不使用例外的正当理由是,如果由于某种原因,他们被禁用(-fno-exceptions)。

答案 4 :(得分:0)

没有跳跃或结果的最佳方法是检查返回并执行while循环:

    void myFunc(char *s) {

      bool doneAll = false;
      int res = 0;

      do {
        res = doSomething(s);
        if(!res) break;
        res = doSomethingElse(s);
        if(!res) {
          break;
        } else { 
          doneAll = true;
        }
      while (false); // no really a loop, a smart way of using breaks
      // you know can access doneAll to check if everything is done

      // Any cleanup here as well
    }

答案 5 :(得分:0)

另一种方法 - 使用全局错误标记。

static int found_error = 0;

void anyFunction(char *s) {
    if (found_error) return;

    if (something_failed) {
        found_error = 1;
        return;
    }
}

现在,在检测到错误后,仍会调用某些函数,但不执行任何操作。