SharpHawk
SharpHawk

Reputation: 398

How are error-handling statements formatted?

I have a few functions that return a 1 if an error is encountered. Each function calls on a lower-level function, such that if the lower-level function returns a 1, the original function returns a 1 as well. Thus errors get passed up the chain in this way.

Here's an highly abridged version of one of these functions:

if (low_level_function()) {
    [do stuff]
    return 1;
}
[do other stuff]
return 0;

Should I instead declare an error variable, assign the result of low_level_function() to it, and then use the error variable in the if() statement? In other words:

int error = low_level_function();
if (error) {
    [do stuff]
    return 1;
}
[do other stuff]
return 0;

Or is there yet another, better way of doing this? I've never coded to account for errors before, so my experience here is rather limited.

Edit: I've reformatted the functions to better convey the nature of my code.

Upvotes: 0

Views: 126

Answers (4)

alk
alk

Reputation: 70931

Although it it's s side comment I´ll be first stateing that I prefer one exit for any method.

One major pro tof his construction is the possiblity to only have the need for a error-logging statement at one place.

Also it's very easy to add tracing logs for debugging porpose.

So following this idea I'd propose the following

#define OK (0)

int mid_level_func(....)
{
  log_entry(...);

  int rc = OK

  {
    ...

    if ((rc = low_level_func1(...)))
      goto lblExit;

    ...

    if ((rc = low_level_func2(...)))
      goto lblExit;

    ...

    lblExit:
    ;
  }

  if (OK != rc)
    log_error(rc, ...);

  log_exit(...);

  return rc;
}

For the ones that insist on goto being 'evil' the following variation on the scheme above might help:

#define OK (0)

int mid_level_func(....)
{
  log_entry(...);

  int rc = OK

  do 
  {
    ...

    if ((rc = low_level_func1(...)))
      break;

    ...

    if ((rc = low_level_func2(...)))
      break;

    ...

  } while (0);

  if (OK != rc)
    log_error(rc, ...);

  log_exit(...);

  return rc;
}

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308196

One reason to prefer the second form is when you don't have anything to do in the error case and you want to avoid the stair-step effect of nested if statements.

int error_flag = low_level_function();
if (!error_flag)
    error_flag = second_function();
if (!error_flag)
    error_flag = third_function();
return error_flag;

Of course for that specific example you can really simplify by using the short-circuiting property of ||:

return low_level_function() || second_function() || third_function();

Upvotes: 2

Emmanuel N
Emmanuel N

Reputation: 7449

I dont see the difference between the two approaches above.

I would recomment using exception, much more cleaner approach. why the reinvent the wheel? You can either use standard exception or implement custome exception like

Upvotes: 1

Dewsworld
Dewsworld

Reputation: 14033

You can use this also,

return low_level_function();

If low_level_function() returns nonzero on error and zero on success. Or

return low_level_function()>0? 1 : 0;

Upvotes: 1

Related Questions