Pattern to prevent constant error checking?

Is there a pattern in C that eliminates the need to constantly check for errors in functions that call other functions?

eg. If the function foo () calls a (), b (), and c () one after the other, you must check the return value before continuing. if a (), b () or c () also call other functions, which may also call other functions, this leaves a long sequence of error checking, possibly of 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;
}

, , , ifs, - , , , , .

+3
3

&&, , false, .

a(), b() c(), :

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 ; 
}
+4

, , , . , , , ( ) . , , .

: , ,

err = a(x);
if(err) return err;

#define error_check(f, e) \
e = f; \
if(e) return e;

,

error_check(a(x),err)

, .

+3

, , OP , , , . if (a(x) || b(x)) return true err, a() b().

.

, . , a(x), b(x) c(x), 2, . 3 1, , 1 3 .

# 2 , , .

: , , .

int16_t foo (x_t x, y_t y, z_t z) {  // added matching return type
    int16_t err = 0;

    // OP style 1
    err = a(x));
    if (err) return err;
    err = b(y);
    if (err) return err;
    err = c(z); 
    return err;

    // OP style 2
    err = a(x);
    if (!err) err = b(y);
    if (!err) err = c(z);
    return err;

    // style 3
    // via enum or define, create an OK symbol
    if ((err = a(x)) != OK) return err;
    if ((err = b(x)) != OK) return err;
    if ((err = c(x)) != OK) return err;
    // 
}
+1

Source: https://habr.com/ru/post/1671346/


All Articles