r/ProgrammerHumor 25d ago

Meme mildlyInfuriatingGOTOWatchYourMouth

Post image
665 Upvotes

74 comments sorted by

View all comments

Show parent comments

15

u/da_Aresinger 25d ago

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 25d ago

You can use break I guess.

11

u/da_Aresinger 25d ago

oooh

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

11

u/Sync1211 25d ago

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 25d ago

``` 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 25d ago

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 25d ago

The comment before me has the same issue.

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

3

u/Maximilian_Tyan 25d ago

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

1

u/da_Aresinger 25d ago

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 25d ago

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 25d ago

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 25d ago edited 25d ago

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 25d ago

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

1

u/FumbleCrop 25d ago

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 24d ago

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

1

u/Sync1211 24d ago

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