Deep nesting vs early returns

Claude no at no.no
Fri Oct 5 13:40:41 UTC 2018


On Thursday, 4 October 2018 at 06:43:02 UTC, Gopan wrote:
> Any advices?

In C, I will layout my functions like that (that's especially 
good for initializer functions):

int init(struct my_handle *handle, ...)
{
   if (handle == NULL)
     return -EINVAL;  // direct return for parameter safety check

   if (other_arg > MY_MIN || other_arg > MY_MAX)
     return -EINVAL;  // same here

   handle->data == calloc(1, SIZE);
   if (handle->data == NULL)
     return -ENOMEM;  // return when memory allocation fails,
                      // I assume my program won't recover anyway

   // create some system resource
   handle->fd = fopen("bla.txt", "w");
   if (handle->fd == NULL)
     goto error;  // goto error, because I have some cleanup to do
                  // I will use goto's from now on every time I 
have
                  // some action that return an error

   ...

   return 0; // Success

error:
   close(handle->fd);  // maybe check first fd is valid...
   free(handle->data);
   return -EFAIL;
}


My basic rules are:
1- Argument safety check before anything else, return 
straightaway.
2- If memory allocation fails, return (or assert), no cleanup, 
unless you expect to recover from it, so that is a resource 
allocation like described in the next point.
3- If some resource allocation fails, escape using a goto 
statement to final label. I call it "error" for simple cases, 
else "error_closepipe", "error_epoll" etc, depending on the 
resource I'm cleaning up.
4- error handling is after a successful "return 0;" which 
finalizes a nominal execution flow.
5- Maybe use some "int ret" to carry some error code at the end, 
and maybe log it, for easier debugging.
6- Don't use a return statement in a loop. Break from it: there 
could be some cleanup to do after the loop.

As a side-note, one instruction is one operation, I don't like:

if ((ret = handle->doSomeStuff(args)) < 0)
   goto error;

I prefer:

ret = handle->doSomestuff(args);
if (ret < 0)
   goto error;

It's especially annoying to read (and thus maintain) if some 
other conditions are tested in the if-statement.


More information about the Digitalmars-d mailing list