C++ 测试和报告多函数调用返回错误的技术

C++ 测试和报告多函数调用返回错误的技术,c++,error-checking,C++,Error Checking,我正在研究函数调用中的错误测试和报告技术,特别是在调用多个函数时。作为我的意思的一个例子,为了简单起见,每个函数返回一个bool: success = false; if (fnOne ()) { if (fnTwo ()) { if (fnThree ( )) { success = true; } else { cout << "fnT

我正在研究函数调用中的错误测试和报告技术,特别是在调用多个函数时。作为我的意思的一个例子,为了简单起见,每个函数返回一个bool:

success = false;

if (fnOne ())
{
    if (fnTwo ())
    {
        if (fnThree ( ))
        {
            success = true;
        }
        else
        {
            cout << "fnThree failed" <<endl;
        }
    }
    else
    {
        cout << "fnTwo failed" <<endl;
    }
}
else
{
    cout << "fnOne failed" <<endl;
}
success=false;
if(fnOne())
{
if(fnTwo())
{
if(fntree())
{
成功=真实;
}
其他的
{

cout此代码应该比第一个变体更清晰:

if (!fnOne ())
{
    cout << "fnOne failed" <<endl;
    return;
}
if (!fnTwo ())
{
    cout << "fnTwo failed" <<endl;
    return;
}
if (!fnThree ())
{
    cout << "fnThree failed" <<endl;
    return;
}
success = true;
if(!fnOne())
{

cout如果您确实希望一个函数返回一个表示其他几个函数成功/失败的值(仅此而已-不是每个函数的通用返回值,这需要某种方式返回数组/元组/值向量),那么有一种方法:

int bigFunction()
{ int return_value = 0;

  if (function1() != 0)
    return_value |= (1 << 0);

  if (function2() != 0)
    return_value |= (1 << 1);

  if (function3() != 0)
    return_value |= (1 << 2);

  // ....

  return return_value;
}
int bigFunction()
{int return_value=0;
如果(函数1()!=0)

返回_值|=(1处理代码中的错误(bug)由用户输入引起的错误本身就是一个巨大的主题。您采用的技术取决于代码的复杂性和代码的预期寿命。您在家庭作业项目中采用的错误处理策略比在学期项目中采用的错误处理策略要简单,而学期项目中采用的错误处理策略则不那么复杂与内部项目所采用的错误处理策略相比,内部项目比广泛分发给客户的项目要简单

策略1:写入错误消息并中止

您可以在家庭作业项目中使用的最简单的错误处理策略是将消息写到stdout,然后调用
abort()

下一级错误处理涉及到检测一个坏的输入并使用其他选项处理它。您可以从函数返回一个错误代码。如果您使用C++,则可以抛出异常。这两种选项都是处理大型项目的有效方式。能够支持用户群超出开发团队范围的任何项目

策略3:从函数返回错误代码

int fun3(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun3" came accross a NEGATIVE_INTEGER_ERROR.
    return NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun3
  int ecode = fun3(in);

  // If fun3 had any errors, deal with it.
  if (ecode)
  {
     return;
  }

  // Rest of the function.
}
void fun4(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun4" came accross a NEGATIVE_INTEGER_ERROR.
    throw NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun4. Be prepared to deal with the exception or let it be
  // dealt with another function higher up in the call stack.
  // It makes sense to catch the exception only if this function do
  // something useful with it.
  fun4(in);

  // Rest of the function.
}
int fun3(int-in)
{
if(in<0)
{
//表示“fun3”出现负整数错误。
返回负整数错误;
}
//函数的其余部分。
}
void funUser(int-in)
{
//打电话给fun3
int ecode=fun3(in);
//如果fun3有任何错误,请处理它。
如果(ecode)
{
返回;
}
//函数的其余部分。
}
策略4:从函数中抛出错误代码(C++)

int fun3(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun3" came accross a NEGATIVE_INTEGER_ERROR.
    return NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun3
  int ecode = fun3(in);

  // If fun3 had any errors, deal with it.
  if (ecode)
  {
     return;
  }

  // Rest of the function.
}
void fun4(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun4" came accross a NEGATIVE_INTEGER_ERROR.
    throw NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun4. Be prepared to deal with the exception or let it be
  // dealt with another function higher up in the call stack.
  // It makes sense to catch the exception only if this function do
  // something useful with it.
  fun4(in);

  // Rest of the function.
}
void fun4(整数英寸)
{
if(in<0)
{
//表示“fun4”出现负整数错误。
抛出负整数错误;
}
//函数的其余部分。
}
void funUser(int-in)
{
//打电话给fun4。准备好处理异常,或者听其自然
//处理调用堆栈中较高级别的另一个函数。
//只有当此函数执行以下操作时,捕获异常才有意义
//一些有用的东西。
fun4(in);
//函数的其余部分。
}

希望这能为您提供足够的背景知识,以便为您的项目采用适当的错误处理策略。

您忘记了一个变体(第一个变体):
boolr1=fnOne(),r2=fnTwo();r3=fnthour();if(r1&&r2&&r3){/*做点什么*/}其他{/*做点别的*/}“例外”是C++的一种选择,我看到它使用(主要是不幸的是,不必告诉你我的恐怖故事),而不是C(容易地和干净地)。根据这个事实:我喜欢这种方法,我意识到这个话题与哲学有关,是否应该使用“返回”。在每个函数的不止一个位置。我通常不这样做,因为我有过很多不好的经验,调试大型代码时,会进入多个级别的条件,然后突然退出。像这样使用返回平面,我认为是分散的,它有助于区分状态机和错误处理。问自己这样的问题:是吗如果fnOne失败,可以吗?程序是否可以正常恢复?如果可以,也许您的问题可以从使用状态机中受益。否则,我会抛出异常。但这是基于观点的,所以请进行实验,看看在您的场景中如何工作。关于缩进:在我看来,对于任何函数,最好不要使用超过两个级别。
void fun4(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun4" came accross a NEGATIVE_INTEGER_ERROR.
    throw NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun4. Be prepared to deal with the exception or let it be
  // dealt with another function higher up in the call stack.
  // It makes sense to catch the exception only if this function do
  // something useful with it.
  fun4(in);

  // Rest of the function.
}