all 10 comments

sorted by: hot top controversial new old
[–] 12 points 1 year ago

IIRC, this is because gcc optimizes goto very well, or at least it did back in the day. It also is a genuinely workable solution for error handling in C.

Consider if you need to setup three things, do something with them, and then tear them down in reverse order. If there's an error on the second thing, you want to jump right to the part where you tear down the first thing. Using goto tends to make cleaner code for that in C compared to, say, nested conditionals.

  • source
  • [–] 10 points 1 year ago

    but how many COMEFROMs are there

  • source
  • [–] 7 points 1 year ago

    Really nice combination of data and presentation.

  • source
  • [–] 5 points 1 year ago

    I'm pretty certain this has traumatized me.

  • source
  • ~200000 in ~73 million isn’t so bad, right?

  • source
  • [–] 4 points 1 year ago

    Seems like it's mostly error handling, which makes total sense to me. In a function with a lot of error conditions, where it also takes more than return <nonzero value> to report that error, the code would get very cluttered if you handle the errors inline. Using goto in that case makes the normal case shorter and more readable, and if proper labels are used, it also becomes clear what happens in each error case.

    Sure, you can do that with functions too, but it's much nicer staying in the same scope where the error occurred when reporting on it. Putting things in a function means thinking about what to pass, and presents extra resistance when you want to report extra info, because you have to change the function signature, etc.

  • source
  • [–] 2 points 1 year ago

    On Error Resume Next

  • source
  • [–] 3 points 1 year ago* (2 children)

    Go-To's are just a primitive functions that dont isolate code, just use functions.

  • source
  • hideshow 2 child comments
  • [–] 5 points 1 year ago*

    Not really. There are quite a few of structures you can make with gotos that can't directly be translated into functions. Sure, you can implement any functionality in any programming paradigm, but it might require much more work than to just replace goto with a function call.

  • source
  • parent
  • [–] 3 points 1 year ago

    In C, goto is basically a necessity though. There is really no good way of error handling.

    Options:

    1. Using goto
    void func(void *var) {
        void * var2 = malloc();
        if var == Null {
            goto err;
        }
    
        do_something();
    
    err:
        free(var2);
    }
    
    1. Early returns:
    void func(void *var) {
        void * var2 = malloc();
        if var == Null {
            free(var2);
            return;
        }
    
        do_something();
    
        free(var2);
    }
    
    1. Skipping with conditionals:
    void func(void *var) {
        bool error = false;
        void * var2 = malloc();
        if var == Null {
            error = true;
        }
    
        if !error {
            do_domething()
        }
    
        free(var2);
    }
    
    1. Early return + cleanup function.
    void cleanup(void *var2) {
        free(var2);
    }
    
    void func(void *var) {
        void * var2 = malloc();
        if var == Null {
            cleanup(var2);
            return;
        }
    
        cleanup(var2);
    }
    

    Option 1 is really the only reasonable option for large enough codebases.

    Option 2 is bad because duplicate code means you might change the cleanup in one code path but not some other. Also duplicate code takes up too much valuable screen space.

    Option 3 has a runtime cost. It has double the amount of conditionals per error point. It also adds one level of indentation per error point.

    Option 4 is same as option 2 but you edit all error paths in one single place. However, this comes at the cost of having to write 2 functions instead of 1 for every function that can error. And you can still mess up and return while forgetting to call the cleanup function.

    You must also consider that erroring functions are contagious, just like async ones. I'd say most of the time a function is propagated upwards, with very few being handled just as it ocurrs. This means that whichever downside your option has, you'll have to deal with it in the whole call stack.

  • source
  • parent
  • 3 comments in c/linux@programming.dev view that post
    [–] 3 points 1 year ago (1 child)

    People who think gotos are bad like Dan Brown novels.

  • source
  • hideshow 1 child comment
  • [–] 7 points 1 year ago

    Gotos being bad falls in the it depends category.

    Bad:

    • When you think you're going to do something clever (when you should probably be reaching for a different tool that you may or may not know exists)

    Good:

    • When in the form of a jump that's was written by a sound compiler
    • When learning how assembly works
    • When working on codecs and you're actually going to spend the many hours to get everything right.
    • Labelled breaks in nested for loops
    • Embedded systems when resources are constrained
    • When writing debuggers
    • When writing anti-cheat systems
    • And finally, when you actually need to because you're manually managing things (e.g. you're writing a kernel)
  • source
  • parent
  • [–] 2 points 1 year ago

    goto is the standard way of performing error handling in C, since there is no exception system or destructor mechanism to free resources when they are going out of scope.

  • source