Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Considering the harmful

Name: Anonymous 2008-04-23 19:14

So when writing C code and you have a function that allocates stuff and other things that needs to be cleaned up, how do you make things not to look like a mess when errors happen? For example (with return 0 for ok, and return 1 on error)

if ((a = AllocA()) == NULL)
    return 1;
if ((b = AllocB()) == NULL) {
    FreeA(a);
    return 1;
}
if (SomeInit() != INIT_OK) {
    FreeA(a);
    FreeB(b);
    return 1;
}
while (something) {
    if (error) {
        FreeA(a);
        FreeB(b);
        SomeCleanup();
        return 1;
    }
}
if (tarballs) {
    FreeA(a);
    FreeB(b);
    SomeCleanup();
    return 1;
}
return 0;

There's a lot of repitiion in that. What I'd really want would be something analogous to atexit() for the current scope. The only way that doesn't repeat all that I've thought of is through goto like

if ((a = AllocA()) == NULL)
    return 1;
if ((b = AllocB()) == NULL)
    goto free_a;
if (SomeInit() != INIT_OK)
    goto free_b;

while (something) {
    if (error)
        goto free_all;
}
if (tarballs)
    goto free_all;
return 0;

free_all: SomeCleanup();
free_b: FreeB(b);
free_a: FreeA(a);
return 1;

What is /prog/'s thoughts on this situation?

Name: Anonymous 2008-04-24 1:19

Yeah, >>17 is kindof nuts. Putting a bunch of code to gracefully exit the program *INSIDE malloc()!!!!* is an incredibly horrible idea. No wonder he hates C++, he has no concept of encapsulation.

As for >>1, the example code you're giving is actually fairly esoteric in practice. If you're going to be allocating several memory segments on the heap in this function, then the function is likely performing a rather large operation, in which case the malloc/free error checking is pretty small in comparison.

Also, you know what else helps? LOTS OF WHITESPACE. I like to separate my code into logically organized "paragraphs", with each "paragraph" having a comment explaining what's going on.

int func() {

  //allocate memory
  int* a, b;
  if ((a = malloc(100 * sizeof(int)) == NULL)
    return -1;
  if ((b = malloc(100 * sizeof(int)) == NULL) {
    free(b);
    return -1;
  }

  //do stuff
  if (!something(a) || !something(b)) {
    free(a); free(b); return -1;
  }

  //clean up
  free(a);
  free(b);
  return 0;

}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List