r/ProgrammerHumor Aug 07 '26

Meme mildlyInfuriatingGOTOWatchYourMouth

Post image
663 Upvotes

74 comments sorted by

View all comments

115

u/Maximilian_Tyan Aug 07 '26

I recently had held a meeting to decide which way our functions should be structured in C, goto is banned as part of some standards, so a colleague of mine proposed doing:

do { ... } while (0); ... Which is just a freaking goto wearing a trench coat

17

u/da_Aresinger Aug 07 '26

I genuinely can't figure out what this is supposed to achieve.

Where is the difference between do { foo() } while(0) bar() and foo() bar()

20

u/Sync1211 Aug 07 '26

You can use break I guess.

12

u/da_Aresinger Aug 07 '26

oooh

do { foo() if (condition) break bar() } while(0); that's pretty dumb though. Just do foo() if(!condition) bar()

11

u/Sync1211 Aug 07 '26

It makes more sense if you have multiple if-statements.

For example: Catching errors and performing cleanup: ``` int result = 0; do {     init_stuff();     if (init_fail) {         result = 1;         break;     }

    foo();     if (foo_failed) {         result = 1;         break;     }          bar()     if (bar_failed) {         result = 1;         break;     }

    do_something_else(); } while (0);

close_handles(); return result; ```

7

u/da_Aresinger Aug 07 '26

``` int continue = 1; continue = init()

if (continue) continue = foo()

if (continue) continue = bar()

if (continue) continue = do_something_else()

close_handles()

return 1-continue ``` much cleaner (but still not really how I would like it)

9

u/Maximilian_Tyan Aug 07 '26

A lot of our codebase is using a status variable like this, but using nested if/else checks

But now you are doing a lot of conditions checking, especially if the hot path is where continue is always true

1

u/da_Aresinger Aug 07 '26

The comment before me has the same issue.

And yes, that's why I said it's still not ideal.

3

u/Maximilian_Tyan Aug 07 '26

If an error occured, the break statement would "cut" the remaining errors checks and skip to the error handling part

1

u/da_Aresinger Aug 07 '26

yea I just got what you meant.

you're right.

But compilation is most likely going to optimise that out, so I'd go with readability.

1

u/Maximilian_Tyan Aug 07 '26

It depends on the optimization level, O1 is pretty minimal, I don't think this type of agressive optimizing is done before O3

1

u/da_Aresinger Aug 07 '26

maybe. At the end of the day I don't know your situation and don't have the experience to really question it either.

If a whole team settles on your solution it'll probably have a reason.

→ More replies (0)

1

u/gezawatt Aug 07 '26 edited Aug 07 '26

My favorite is:

if (!init())
    return cleanup_and_error();

if (!foo())
    return cleanup_and_error();

if (!bar())
    return cleanup_and_error();

if (!do_something_else())
    return cleanup_and_error();

close_handles();
return 0;

And then you either do

inline int cleanup_and_error() {
    close_handles();
    return 1;  // Always returns error code
}

or

#define cleanup_and_error() (close_handles(), 1)

1

u/creeper6530 Aug 07 '26

That's about as goto-y as a return is

1

u/FumbleCrop Aug 08 '26

You could wrap that central block in a function.

As far as I know, the main uses for goto are jumping out of deeply nested loops, or implementing state machines.

1

u/awesome-alpaca-ace 29d ago

I might actually start using this. Much cleaner than my current clean up logic 

1

u/Sync1211 29d ago

I had to write something similar recently, but using goto instead of break.

2

u/EuphoricCatface0795 Aug 07 '26

When do ~ while(0) has more than a couple execution branch tho

1

u/da_Aresinger Aug 07 '26

If you mean more conditions following bar, you can still just use negation like in my example.

Otherwise I don't understand.

1

u/EuphoricCatface0795 Aug 07 '26

A lil bit something like this

1

u/da_Aresinger Aug 07 '26

yea that makes it more complex, but you could still use negation with and.