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

Pages: 1-4041-

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-23 19:16

DON'T

Name: Anonymous 2008-04-23 19:35

>>1
How about this? It keeps track of the `'error indentation`', so to speak, using a separate variable, and then applies the appropriate cleanup code depending on that value.


int e = 0; // error level

if ((a = AllocA()) != NULL)
    if ((b = AllocB()) != NULL) {
        if (SomeInit() == INIT_OK) {
            while (something) {
                if (error) {
                e = 4;
                break;
                }
            }
            if (e==0 && tarballs) {
                e = 4;
            }
        } else e = 3; // if someinit failed
    } else e = 2; // if allocb failed
} else e = 1; // if alloca failed

// use error level to determine what cleanup is needed
switch(e)
{
    case 4: SomeCleanup();
    case 3: FreeB(b);
    case 2: FreeA(a);
}

// and then use error level to determine return value
return ((e>0)?1:0);

Name: Anonymous 2008-04-23 20:08

throw exception AllocationError();

Name: Anonymous 2008-04-23 20:13

man setjmp
man longjmp

Name: Anonymous 2008-04-23 20:23

>>5
Ugh, messy.

Name: Anonymous 2008-04-23 20:26

Simple, if malloc fails, exit the program, because fuck. If it is a library you are writing and malloc fails, return an error value.

Name: Anonymous 2008-04-23 20:29

>>7
Exactly. If a malloc() call fails, then there's probably not much more your program could do, except maybe tell the user to get more RAM and/or increase the pagefile size.

Name: Anonymous 2008-04-23 20:39

>>7,8
No, you don't just want to exit the program, the user would find that most odd. At the very least, display an error message and then exit.

Name: Anonymous 2008-04-23 20:52

>>9
No shit, I thought any self-respecting EXPERT PROGRAMMER would realize this.

Name: Anonymous 2008-04-23 20:58

>>9
That's more or less what >>8 said - way to agree by disagreeing and rephrasing!

Name: Anonymous 2008-04-23 21:03

>>4
NO EXCEPTIONS

Name: Anonymous 2008-04-23 21:08

>>1
There are many solutions of which one includes writing your own malloc wrapper like:

void * mymalloc(malloc_t *instance, size_t size);

Then

void myfree(malloc_t *instance, void *ptr);
void myfreeall(malloc_t *instance);

Etc.
Basically, you do what your OS does. Keep track of allocation/frees and free them all in the end.

Name: Anonymous 2008-04-23 21:13

Another possible solution is not worrying and adding Hans Boehm's garbage collector. Never again will you have to worry about pesky free and malloc! I feel kind of bad about it :(

Name: Anonymous 2008-04-23 21:27

>>3
that's worse.

fuck dijkstra, just use goto.

Name: Anonymous 2008-04-23 21:44

10 GOTO 10

Name: Anonymous 2008-04-23 21:45

Name: Anonymous 2008-04-23 22:23

>>17
Time for debunking...
I'm going to skip point 1 which is just too damn stupid.
I don't think he's aware that malloc() can fail for a number of reasons, and not just "process out of memory".

Let's start with 2:
2. Casting void-star
Excuse me, but WHO THE FUCK calls void * ``void-star''?
What the FUCK. At that point I thought he was trolling.
It’s the void pointer’s job to stand in for other pointer types.
No, that's a terrible lie. void * is there for a number of reasons, (proper alignment, polymorphism) but it's not for all pointers.
Only for pointers to objects.

In ANSI C99
No, you mean in ISO C99. ANSI wrote C89.
the “cast” is implied
There are implicit conversions, but not implicit (or explicit) casts.
when you pointers to or from void-star
When I pointers to or from? Ok. That made sense.

But the redundant int-star cast isn’t just extra noise. Because the “implicit cast” behavior is unique to void-star, casting explicitly hides an error: if variable types change (say, you add an argument to a function), and what you thought was a void-star ceases to be a void-star, a casted assignment will suppress a
The reason the cast is avoided in C in malloc and friends is because if the prototype is missing compilers will assume the functions return an ``int''. ints are not guaranteed to hold a pointer correctly, and therefore all sorts of problems might arise.
Nothing remotely related to what you are trying to say.
And look askance at ANY pointer cast in straight C code.
I can think of two examples where it is necessary

/* 1 */
char *p = "hello world";
printf("%p\n", (void *)p);
/* 2 */
execl(path, path, arg1, arg2, (char *)0);


Less typing, safer code.
Hah, false premises.

Now, to 3

3. Passing pointers to tiny structures
You want to return a pointer to a buffer and its length. You use the equivalent of:
struct iov {
u_char *base;
size_t len;
};

Well, that's not how iov is declared in POSIX. man 3 readv for details.

On LP32, struct iov is as hard to pass in and out of a function as long long.
In ISO C99, you don't have to pass or return structures by pointer. Since you mentioned long long (which is C99), then on LP32 you can pass structures as is.

Put differently, unless you go out of your way to individually allocate and pass pointers to long long to avoid the “overhead” (use of successive registers) of copying, you don’t get to pass pointers to struct iov.
I'm not sure what you are trying to say, but it's not C.

Dragging the point out further, I could say that if you use long long in your code, you should be passing “pair” structs instead of using out-args to store lengths. But I’m not going to go there, because that’d be hypocritical even if it was correct.

It's not. It invokes undefined behavior. You are a hypocrite anyway. Read the god damn C99 standard (protip: It's from ISO. Not ANSI YOU MORON)

Less typing, safer code.
I'm gonna fucking suicide.

Moral cousin to gripe (2). You can “dereference” an undefined pointer in a “sizeof” expression. So this:

No, you cannot. Try this:
int (*n)[*];
So, maybe you should leave VLAs out. Even then, it's not what you can do. It's what sizeof does. sizeof does not evaluate its operand, with some exception rules for VLAs

As for your malloc example, it's a known idiom.

So tl;dr your cretinous article is full of mistakes, inaccuracies, hypocrisy and fail. http://www.matasano.com/log/consulting-services/
I lold ^. Kids these days.

Name: Anonymous 2008-04-23 23:17

>>18

IHBT

Name: Anonymous 2008-04-23 23:39

stopped reading at ``malloc() can fail for a number of reasons, and not just "process out of memory"''

Name: 18 2008-04-24 0:02

>>21
Really? Why?
Consider a signal or overcommiting.

Name: Anonymous 2008-04-24 0:38

>>18

I think the main point still stands, which is that keeping your malloc-failure-handling logic in one place is better than shitting up your code with checks for NULL everywhere.

Name: Anonymous 2008-04-24 0:45

>>22
What I think is that he is an inexperienced programmer in no place to tell me what to do and how to manage my malloc pointers.
Seriously, that guy's a faggot. Just accept it and move on his point doesn't stand, learn2design programs.

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;

}

Name: Anonymous 2008-04-24 1:23

>>24
//allocate memory
Thanks for telling me, I couldn't figure that out myself just by looking.

Name: Anonymous 2008-04-24 1:23

>>24
oh btw your example has a memory leak when malloc the second time that it's called returns NULL. You fail big time.

Name: Anonymous 2008-04-24 1:27

>>26-1000

All trolled by >>24

Name: Anonymous 2008-04-24 1:29

>>26
It's not a leak, it's freeing a NULL pointer. Also, YHBT.

Name: Anonymous 2008-04-24 1:39

>>28
No, I was refering to you NOT free()'ing "a".
You free b which is NULL, and free(NULL) is defined and does nothing. but you don't forget a.
As I said, memory leak. You suck dick, and no, I haven't been trolled. You failed.

Name: Anonymous 2008-04-24 1:41

>>29
What's the usefulness of freeing a NULL pointer? YHBT twice.

Name: Anonymous 2008-04-24 2:20

What's the usefulness
Philosophical questions now?
 
free()  frees  the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().  Otherwise, or if free(ptr) has
already been called before, undefined behaviour occurs.  If ptr is NULL, no operation is performed.

You forget to free "a".

Name: Anonymous 2008-04-24 3:09

==NULL considered verbose. Use ! instead.

Name: Anonymous 2008-04-24 5:17

As an EXPERT PROGRAMMER I much prefer >>3 to >>1 or >>24.

Name: Anonymous 2008-04-24 5:29

>>33
And I prefer drinking piss than eating shit but that doesn't mean I'm going to do any of those.

Name: Anonymous 2008-04-24 5:33

>>34
You've tried both?

Name: Anonymous 2008-04-24 5:50

Im totally learning python or ruby. C is so passe`

Name: Anonymous 2008-04-24 6:26

>>36
Passé!

The accent is acute, not grave.

Name: Anonymous 2008-04-24 7:44

Christophér

Name: Anonymous 2008-04-24 9:31

>>37
sorry, i dont have a faggot keyboard

Name: Anonymous 2008-04-24 9:36

>>39
Touché.

Name: Anonymous 2008-04-24 9:39

Plutôt Christophe

Name: Anonymous 2008-04-24 9:39

>>39
us-intl

Name: Anonymous 2008-04-24 9:49

>>39
In Windows, Ctrl+Alt+e
On a Mac, Opt+e followed by another e
In Linux, AltGr+; followed by e

Name: Anonymous 2008-04-24 9:54

>>43

Name: Anonymous 2008-04-24 9:55

im on windows and used altgr+e: éééééééééééééé  ÉÉÉÉÉÉ  óóóó ííí


ééúúííóó
áá

Name: Anonymous 2008-04-24 11:07

h€x my €n€s

Name: Anonymous 2008-04-24 14:04

0123456789öüóqwertzuiopőúasdfghjkléáűíyxcvbnm,.-

Name: Anonymous 2008-04-24 14:43

The >>3 way seemed ok, as it also allows you to return e as an error code for each possible situation that might occur. However there's a lot of extra indentation which I don't like. Like Linux said, ``If you need more than four levels of indentation, you're screwed anyway''.

Name: Anonymous 2008-04-24 21:18

҈  НАХ МY АИUЅ  ҉

Name: Anonymous 2009-03-06 6:16

Have THOUGHT OF PROGRAMS   IN FORTRON AND   IM AN EXPERT   PROGRAMMER who wrote   a fast Fuun   compiler and then   added a crapload   of extentions to   it and broke   existing ones so   that it would   be wonderful if   the Gimp had.

Name: Anonymous 2009-03-06 10:27


Just to later learn.

Name: Anonymous 2011-02-03 4:21

Name: Anonymous 2011-02-04 12:57

Name: Anonymous 2011-02-18 13:26

that's cool and all, but check 'em

Name: Sgt.Kabukiman䖉 2012-05-22 23:19

All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy

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