模式防止连续检查错误? [英] Pattern to prevent continually checking error?

查看:159
本文介绍了模式防止连续检查错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C中,是否有一种模式可以消除需要持续检查调用其他功能的函数中的错误?



如果函数foo()一个接一个地调用a(),b()和c(),则在继续之前必须检查每个的返回值。如果a(),b()或c()也调用其他函数,这也可能会调用其他函数,这会导致长时间的错误检查序列可能是相同的错误...

  int16_t a(x_t x){return DO_SOME_WORK(x);} 

int16_t b(y_t y){return DO_OTHER_WORK(y); }

int16_t c(z_t z){return DO_MORE_WORK(z);}

foo(x_t x,y_t y,z_t z){
int16_t err = 0;
//我可以处理由以下两种方法返回的错误:
err = a(x));
if(err)return err;
err = b(y);
if(err)return err;
err = c(z);
return err;

//或
err = a(x);
if(!err)err = b(y);
if(!err)err = c(z);
return err;
}

我喜欢第二种方法,因为有一个明确的单个退出点,但是其他的定位处理和任一方法引入了很多ifs,并且使用一个大的程序,这是很多额外的代码,特别是在函数中,除了调用其他函数,并传递它们之间的输出,例如。
谢谢

解决方案

在这种情况下,您可以利用& amp ; ,当左手操作数为 false 时,不评估右手操作数。



如果您可能希望在调用 a() b()

  bool foo(x_t x,y_t y,z_t z)
{
bool err = a(x);
err = err&&& b(y);
err = err&&& c(z);

return err;
}

而如果函数仅由调用 a () b() c(),那么你可以使用更简洁:

  bool foo(x_t x,y_t y,z_t z)
{
return a (x)&&
b(y)&&
c(z);
}






评论]



解决@ kkrambo关于函数返回的任何数值不被传播给调用者的点可以解决,但是作为一个解决方案越来越不具有吸引力:

  int16_t foo(x_t x,y_t y,z_t z)
{
int16_t ret;

bool err =(ret = a(x));
err = err&&& (ret = b(y));
err = err&&& (ret = c(z));

return ret;
}

  int16_t foo(x_t x,y_t y,z_t z)
{
uint16_t ret;

(ret = a(x))&&
(ret = b(y))&&
(ret = c(z));

return ret;
}






增加可怕的可能性甚至可以:

  int16_t foo(x_t x,y_t y,z_t z)
{
int16_t err ;

if((err = a(x))){}
else if((err = b(y))){}
else if((err = c (z))){}

return err;
}

简化为以下哪里 err 是布尔值:

  bool foo(x_t x,y_t y,z_t z)
{
bool err = true;

if(a(x)){}
else if(b(y)){}
else if(c(z)){}
else {err = false}

return err;
}


In C, is there a pattern that removes the need to continually check for errors in functions that call other functions?

e.g. If function foo() calls a(), b() and c() one after the other the return value from each has to be checked before continuing. if a(), b(), or c() also call other functions, which possibly also call other functions, this leaves a long sequence of error checking of possibly the same error...

int16_t a(x_t x) {return DO_SOME_WORK(x);}

int16_t b(y_t y) {return DO_OTHER_WORK(y);}

int16_t c(z_t z) {return DO_MORE_WORk(z);}

foo (x_t x, y_t y, z_t z) {
    int16_t err = 0;
    // I can handle errors returned by either:
    err = a(x));
    if (err) return err;
    err = b(y);
    if (err) return err;
    err = c(z); 
    return err;

    // Or
    err = a(x);
    if (!err) err = b(y);
    if (!err) err = c(z);
    return err;
}

I prefer the second method as there is a clear single exit point, but the other localises the handling and either method introduces a lot of ifs, and with a large program, that's lots of extra code, especially in functions that do nothing but call other functions and pass along the output between them, for example. Thanks

解决方案

In this case you could exploit short-circuit evaluation of &&, where when the left hand operand is false, the right-hand operand is not evaluated.

If you might want to perform other processing between calls to a(), b() or c(), the following allows that:

bool foo (x_t x, y_t y, z_t z) 
{
    bool err = a( x );
    err = err && b( y ) ;
    err = err && c( z ) ; 

    return err;
}

whereas if the function is composed solely of calls a(), b() or c(), then you can use the even more terse:

bool foo (x_t x, y_t y, z_t z) 
{
    return a( x ) && 
           b( y ) && 
           c( z ) ; 
}


[added in response to comment]

Solving @kkrambo's point about any numeric value of the function return not being propagated to the caller can be solved but is increasingly less attractive as a solution:

int16_t foo (x_t x, y_t y, z_t z) 
{
    int16_t ret ;

    bool err = (ret = a( x ));
    err = err && (ret = b( y )) ;
    err = err && (ret = c( z )) ; 

    return ret ;
}

or

int16_t foo (x_t x, y_t y, z_t z) 
{
    uint16_t ret ;

    (ret = a( x )) && 
    (ret = b( y )) && 
    (ret = c( z )) ;

    return ret ; 
}


Increasing in horribleness you could even do:

int16_t foo (x_t x, y_t y, z_t z) 
{
    int16_t err ;

    if( (err = a(x)) ) {}
    else if( (err = b(y)) ) {} 
    else if( (err = c(z)) ) {}

    return err ; 
}

Simplifies to the following where err is boolean:

bool foo (x_t x, y_t y, z_t z) 
{
    bool err = true ;

    if( a(x) ) {}
    else if( b(y) ) {} 
    else if( c(z) ) {}
    else { err = false }

    return err ; 
}

这篇关于模式防止连续检查错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆