1. 21
  1. 13

    AFAIK, one of the big wins Fortran has that C doesn’t, that this article doesn’t mention, is the fact pointer usage is more restrictive, as if restrict was on in C by default. This provides more opportunity for optimizations.

    1. 13

      without the use of goto, so don’t even go there

      Why not? What’s the difference between “break loop1” and “goto after_loop1”? It should be completely equivalent behaviour, right?

      1. 7

        Some people just blindly believe “goto is bad”.

        1. 4

          Pity. Dijkstra was right to crack down on unstructured programming, but right now in my day job, goto makes some error handling patterns much easier.

          I must call several stateful functions, and need to abort and clean up if any of them fails. A simple goto exit; saves me from the horrendous pyramids I see so often. And since those functions return the same error codes, I could easily wrap them in a macro that does logging and error handling for me. That way the main code highlights the happy path, and error handling is kept neatly separate.

          1. 2

            Error-handling with goto is the style used in unix kernels, so your day job is in good company. Typically they do it without macro magic though. error = fallible_thingy(); if (error) goto end; is how all of FreeBSD is written.

            For fresh projects that only care about clang&gcc though you can just go ahead and use the cleanup attribute to basically feel like you have destructors :)

            1. 1

              Why don’t you just defer {} and use a labelled break?

              1. 2

                Because ISO C has neither a defer statement nor labelled breaks. Are you suggesting I use compiler extensions?

                1. 1

                  A BASIC or FORTRAN programmer would probably have said the same thing regarding GOTO.

                  1. 1

                    And your point is?

                    1. 1

                      That’s my point. Goto looks like a go-to tool if your toolbox is limited.

                      1. 1

                        Well… yeah. I do use goto to emulate higher-level constructs, but what I really want is defer. Labelled breaks sound also very nice, though in practice I’ve hardly ever needed them.

              2. 1

                Another alternative to goto is using a do/while(false) loop with break. Here’s a C++ example from an old program I have been hacking on.

                    [[nodiscard]] static fts_result
                    data_accept(server_ptr sh, int &data, file_null_ptr &d_fpin)
                    {
                            sockaddr_in from;
                            socklen_t fromlen = sizeof(from);
                            bool ok = true;
                            do
                            {
                                    const int s = accept(data, to_sockaddr(from), &fromlen);
                                    if (ok = s != -1; !ok)
                                    {
                                            serror(sh, "FTS: data accept");
                                            break;
                                    }
                                    data = s;
                
                                    // Open input stream...
                                    d_fpin = fdopen(data, "r");
                                    if (ok = d_fpin != nullptr; !ok)
                                    {
                                            serror(sh, "FTS: data fdopen");
                                            break;
                                    }
                            } while (false);
                            if (!ok)
                            {
                                    close(data);
                                    data = -1;
                                    return (fts_result::ERR_SYSTEM);
                            }
                            return (fts_result::OK);
                    }
                
                1. 3

                  I have two problems with this approach, one of which is a deal breaker:

                  • This introduces an unnecessary level of indentation. Annoying, but I can work with that.
                  • If there’s any nested switch or loop, I can no longer jump out all the way to the end with a simple break. That’s the deal breaker.

                  I’ll do it if QA is stupid enough to forbid goto in all circumstances I’ll use exceptions if I’m writing C++, and I’ll use your method if I’m writing C. I will also think about finding another job.

          2. 9

            Probably more “C-like languages” have the “exiting from a nested loop” feature than not. Java, Go, Rust, Nim, Perl, JavaScript, D, and Swift all have labeled break. C, C++, C#, and ObjC don’t. So it seems to be something about actually having “C” in your name.

            1. 1

              When my wife did physics… the biggest advantage of Fortran was “auto double” on ye olde mainframes.

              Develop and debug numerics intensive code on single precision arithmetic…. and for the loong runs for the final result, turn on auto-double (or auto quad I think too if I remember very old memories) for increased precision (but slower runtime).