Hacker News new | past | comments | ask | show | jobs | submit | droprip's comments login

I am not very familiar with low level C or the coding patterns used with it, so I must ask; why do we see goto statements in both of these recent bugs? As far as I know it's a bad practice overall, is there some specific reason for using it here?


In short, it's not a bad practice in all cases and, like most issues, it depends.

The "goto considered harmful" article by Dijkstra is more nuanced (and that wasn't even its intended title) and doesn't really address the way the goto you are seeing are used.

They are a very common pattern in C, for error checking and cleanup in case of error. It's much more readable than to nest conditional statements.

  if (some_parameter > max_valid_value)
    goto error;
  if (some_function() <= )
    goto error;
  ...
  ...
  if (some_alloc() == NULL)
    goto error;
  ...
  ...
  ...
  ...
  error:
    // cleanup what needs to be freed,...
It can also be quite useful to exit nested loops for example. It's commonly used in low-level C.

However, when you start goto'ing backwards instead of always forwards, it becomes terrible for readability, so it is avoided (well, most of the time).

For more reading on the subject, this excerpt from Code Complete by Steve McConnell discusses the subject further : http://www.stevemcconnell.com/ccgoto.htm


Since C has neither garbage collection nor the RAII pattern of C++, it is very common for C functions to have a cleanup section at the end, where allocated memory and other resources are freed again. In many C projects (including the Linux kernel) it is a common and accepted pattern to jump into the right position of the cleanup sequence using a goto.


Goto is an acceptable and idiomatic way to implement error handling. If something goes wrong in an inner loop, you can just break out of all the loops and go to the failure state.

e.g. https://stackoverflow.com/questions/788903/valid-use-of-goto...


goto statements are not necessarily a bad practice. Many people have heard the title from a famous letter by Dijkstra, 'Go-to statement considered harmful' (see https://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF). In it he argues against the unrestricted use of goto statements making control flow hard to follow. The title is catchy and stuck in the collective computer science consciousness. It lead to all kinds of 'X considered harmful' articles.

In response to Dijkstra's letter, Knuth wrote the article 'Structured Programming with go to Statements' (http://cs.sjsu.edu/~mak/CS185C/KnuthStructuredProgrammingGoT...). He defends certain uses of goto, such as error exits.


And the articles you quote are BULL FUCKING SHIT


What's wrong with them? If one is bad, the other contradicts it.

Both cannot be wrong can they? It is a logical impossibility.


The correct way to do error handling in C is using goto statements. Dijkstra did not mean local goto statements. He meant something you will not find in any C code you are likely to use on a rhel/debian machine.


C doesn't have exceptions, so goto is commonly used to emulate that style of programming.


It's not just that, it also doesn't have automatic destruction of objects, so any local array or structure containing a pointer needs to be laboriously freed by hand.

And in other words, nobody should be writing anything in C. Ever. The need to be compatible with programs written in C violates my rule against writing anything in C and is therefore not a valid reason to write crypto stacks in C.


> And in other words, nobody should be writing anything in C. Ever.

And in other words, nobody should be listening to thrownaway2424. Ever.


Pure C does not have automatic destruction of objects, but gcc has an extension to do it. Take a look at systemd's source code to see it in action. It's very similar to C++'s RAII, and can also do things like closing file descriptors.


You realize that most lower things are written in or base on C, right.


Yes I am fully aware of the sad state of our industry.


I'm curious, what do you propose the industry use?


Would love to hear the answer to this as well. For the types of thing C is used for, I do not know of another language that can _practically_ be used for the same thing, while maintaining the same level of performance. Rust looks promising but is not mature yet.


You've never heard of C++?


Like BeOS!


C++11? (runs away...)


Isn't Go designed to fill this niche? It's supposed to be a low-level systems language, but with "friendlier" features than C, and built-in concurrency support.


They kind of recanted that statement and said they meant it for "web servers" and stuff like that. However I know there has been at least a window manager made in Go.

I don't think it's the best fit, but it's a lot better than many current solutions. I personally prefer Haskell for anything others would write in Go, however many may find Ocaml or Erlang to fit them better.

However I'm biased and believe that functional programming is a better fit, more bug-free, easier, and simpler for most use cases than imperative programming.


Go is advertised as a systems language but certain things like the lack of manual memory management say otherwise.


Before there was C, there was Pascal. You didn't have malloc in Pascal. At ETH Zurich the standard OS was written in Oberon: it ran directly on the hardware with a garbage collector collecting everything.


Go also has a very highly quality crypto implementation. It has all of the good-code features that gnutls lacks: comments that make sense, unit tests, automatic memory management (of course), useful types, etc.

Compare http://golang.org/src/pkg/crypto/x509/x509.go to https://www.gitorious.org/gnutls/gnutls/source/6aa26f78150cc...



It's amusing but I never thought of exceptions as gotos. But that's what they in essence.


How are exceptions like gotos? I don't see any similarity. If by "essence" you mean they jump to a specific line of code, then lots of things can do that - switch/case , if/else, do/while, function calls/returns, etc.


Apart from the other reasons mentioned here, it probably translates to compact code which fits well within level-1 instruction cache in modern CPU when translated into assembly, without any need for additional lexical scopes and stack allocations.


goto is just a tool and not to blame here. I don't know what you could call the root case of this one. Incomplete testing maybe?

In Apple's case "goto" made it possible for the bug to occur, but there's no reason a different statement (or other typo) could cause equivalent damage.

I think a common thread with both of these bugs is testing the failure cases, but to be fair to both validating software by finding bugs and/or validating functionality is affirming the consequent and you eventually need to ship.


> I don't know what you could call the root case of this one.

Bad software engineering. Their internal routines return negative value to indicate failure, but to the caller they translate it to true/false.


I'm interested in knowing what principles you used to judge goto as a bad practice?

Or do you just mean that its abused a lot? (in which case, I'm less interested.. :) )


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: