1. 6
  1. 26

    Ah, this “awkward squad”.

    The C language’s goto, I believe, is limited within function scope. It’s not nearly as dangerous as BASIC’s version, which allows you to warp anywhere in the program. Assembly code has unrestricted jmp, which is just poking the instruction pointer, but that’s bad in source code. What makes C’s goto reasonable or abhorrent is the size of the function. If you have a 20,000-line function, then it can exacerbate your problems but it isn’t the only one.

    For non-local jumps in C, you have to use setjmp and longjmp, which have their own restrictions.

    With multiple inheritance, the problem is often inheritance. Object-oriented programming has some use in terms of managing allocated blocks of memory, but in general, object-ness is a complication relative to declarative data that we should only use when it’s absolutely needed, and the number of cases where even regular inheritance, much less multiple inheritance, are the cleanest model, is small.

    With eval, I generally agree that it doesn’t necessarily deserve a bad rap, but it’s usually a sign that you’re doing something wrong. But as always, there are exceptions.

    Recursion doesn’t belong on this list, in my opinion. It’s not weird, and it’s only a problem because a lot of languages have mediocre compilers that can’t handle it. (A good compiler will generate fast, iterative code when possible.) The only environments where I’d put recursion on the “please avoid” list are low latency environments (if recursion depth can’t be known statically) and in embedded systems with very little stack space (at which point, I’d be inclined to favor static memory allocation as much as possible).

    1. 8

      Instead of using goto I like to use a parent and child function instead of goto, the parent does the init and destruction, the child does some work and returns whenever as many times as it feels like. This way the destroy code is always called, it’s effectively like basic, local RAII. Lambdas and classes can be used in C++ to keep the code even simpler.

      Apart from virtual function callbacks, I’m finding that I can usually avoid using inheritence at all, let alone multiple inheritence, composition always wins.

      Recursion is fine as you say, you just need a max depth counter, or you need to manually unroll your recursive functions if you are on restricted hardware.

      1. 8

        Recursion doesn’t belong on this list

        Agreed. As a schemer, it pissed me off seeing that.

        1. 2

          I wonder if he included recursion because it’s recursion.

        2. 3

          The inclusion of recursion is just odd, especially given how much popularity functional programming languages have now, where recursion is often used as a “control structure” in place of loops.

        3. 20

          Evaluating your own code can still be very useful. Some examples include: interpreting JSON data

          WHAT? No. Just, no.

          1. 7

            Reading that made me give up on the rest of the article. Eval has its uses, but it is never, ever, ever, used on user inputted data. That’s the primary reason PHP is a mass of exploits.

          2. 6

            It’s bizarre to think that you don’t need recursion outside of the academic world. Trees and other hierarchies are naturally recursive. You can usually start with an easy-to-understand recursive version and then, if necessary, convert it to an iterative version.

            1. 4

              This article is really bad.

              Goto should not be used. It is a worse way of doing logic control than the other options available to you (if/else, switch, looping.) It has a lot of issues not least of which is that it doesn’t bring with it any code structure. When you use other flow control methods the code involved gets formatted to make this clear. There’s many other reasons not to use Goto but that’s one people often overlook.

              Similarly if you are using eval there is almost certainly a better (safer, more reliable, less prone to hidden behaviors) way to do whatever you are trying to do.

              Multiple-inheritance is mostly a problem because it goes against one of the core principles of OOP; encapsulation. In order to do multiple inheritance right you have to know both of the classes you are inheriting from in detail to understand what you’re going to end up with. There’s more beyond that but I think it mostly should be avoided as well.

              Recursion does not belong with the rest of these and its inclusion shows the author’s lack of knowledge. People do sometimes misuse it but only as much as any other standard feature of programming like a standard for loop.