11 comments

[ 2.7 ms ] story [ 34.5 ms ] thread
Some rather cursed macro magic, but I'm quite proud of the end result compared to the existing library solutions.
(comment deleted)
> The classic solution to do resource management in C is to (ab)use goto

Why "(ab)use" goto ? Use it with pleasure! Solution from Linus Torwalds:

    int somefunc(...) {
        int ret = E_OK;
        FILE *a = NULL;
        FILE *b = NULL;
        FILE *c = NULL;

        if(!(a == fopen("a.txt",...)) {
            ret = E_A_FAILED;
            goto end;
        }

        if(!(b == fopen("b.txt",...)) {
            ret = E_B_FAILED;
            goto end;
        }

        if(!(b == fopen("b.txt",...)) {
            ret = E_C_FAILED;
            goto end;
        }

        /* do your fancy stuff here */

        end:

        if(a)
            fclose(a);
        if(b)
            fclose(b);
        if(c)
           fclose(c);

        return ret;
    }


1. This code is clean and neat.

2. People should read Linux kernel source code as their go to sleep Bible verse.

Mentioned in the footnotes ;)
Ah, ok, sorry. When I see someone to curse goto I become mad! goto statement is God sent gift.
I couldn't implement this defer macro without it.
Btw, using goto to different labels is no good for modern CPUs as it spoils branch predictor. In classic Linux way it's usually goto to same "end" or "fail" label resulting in more efficient code. Let's hope compiler will rule this out. ;)
What you save in the gotos you "lose" in the ifs.
> This code is clean and neat.

And severely flawed. The (a == fopen...), etc, are certainly not doing what is apparently intended.

Sure. There should be only one =. Sorry.
If you're going to embrace goto, why not go all the way and use multiple exit labels such that you can jump to appropriate point in the cleanup sequence and avoid those conditionals?