6 ms·
> There are currently 1032 goto statements in the Go compiler jumping to 241 labels. Wow, that's really striking. I know that goto statements have their uses b
by thinkpad20 13y ago
> There are currently 1032 goto statements in the Go compiler jumping to 241 labels.
Wow, that's really striking. I know that goto statements have their uses but for something written in the last couple of years to have over a thousand of them is very surprising (it might not be surprising at all for those who write C code all the time). I guess they're mostly just for error handlers?
- azernik 13y agoYeah, there are a lot of them in e.g. Linux kernel code for jumping to end-of-function cleanup. I suspect that in the process of translation to Go most will be replaced by the defer keyword.
- jgrahamc 13y agoFor example: http://golang.org/src/cmd/6g/gsubr.c http://golang.org/src/cmd/6g/gsubr.c Some are for single error return, but others are just to make a nice structure for the code.
- raverbashing 13y agoAh the old C style of function types in a different line. This smells of very old code (as the header testifies)
- awda 13y ago??? This is modern BSD (and probably plan9) style. Here's a line from the header: > Portions Copyright © 2009 The Go Authors. All rights reserved That's pretty recent. And here's BSD style(9): http://www.freebsd.org/cgi/man.cgi?query=style&sektion=9 http://www.freebsd.org/cgi/man.cgi?query=style&sektion=9 The function type should be on a line by itself preceding the function.
- rafekett 13y agowhich line?
- foxhill 13y agothis is a style i still use today (almost) int main (int argc, char **argv) { //body.. } although most people think i'm weird for it..
- lutusp 13y agoYep, that's pretty weird. It harks back to the early days of C. When I first saw the currently recommended form: int main(int argc, char **argv) { //body.. } I thought it was nice but not obviously advantageous, but over the years I've come around to thinking it makes code easier to follow. Even many bash shell scripting guides now recommend a similar form: for x in y; do # body done
- foxhill 13y agoit certainly helps when your function isn't as simple as main..!
- 4ad 13y agoBSD/Plan 9 style is extremely useful because it allows grepping for functions. More specifically, it allows the creation of acme(1) addresses of the form /some/file.c:/^foo where foo is a function. In acme you can just B3-click on that string and it will open the file at the correct function... It is also a pretty common style in the open source world.
- raverbashing 13y agoYou can do that with ctags > It is also a pretty common style in the open source world. Depends, one proeminent C project doesn't use that: the linux kernel
- copergi 13y ago>You can do that with ctags And I can do it without ctags. That's the point. >Depends, one proeminent C project doesn't use that: the linux kernel That doesn't make his statement "depends" at all. A single project not using that style does not contradict it being "pretty common".
- rootbear 13y agoI use that style all the time. I like having the function name start in column 1, it can make searching easier. I do wish that in C1x (for x > 1), they could find a way to let us declare multiple formal arguments of the same type without repeating the type: float my_graphics_hack(float x, y, z, r, g, b, u, v) { ... instead of float my_graphics_hack(float x, float y, float z, float r, float g, float b, float u, float v) { ... which gets really tedious and obfuscates that fact that they are all the same type, especially with the typename is more complex than just "float". When the new syntax was added to ANSI C, it wasn't possible to do multiple variables, for reasons I've forgotten but which I think had to do with forward type references. It would be awfully nice to find a fix for this.
- coherentpony 13y agostructs are a good way to hide away all that state
- rootbear 13y agoAgreed, but there are still times when I end up having several arguments of the same type, and I see no virtue in having to repeat the type for each formal parameter.
- simias 13y agoThat's a poor justification, there are plenty of tools to index and search C(++) code like ctags or cscope, and your example could use a vector or a struct, I have a hard time imagining when a function with such a prototype would be useful in real life.
- clarry 13y agoCompound literals are not too pretty and not too well known. Plus, if you care about c89... So, do you wrap all your values in a struct because the prototype gets too long otherwise? What a chore. Preferring that function names start at the first column to make searching easier is a perfectly good justification. You, on the other hand, seemingly would impose your tools (which have their shortcomings) and workflow on people with no justification at all. Just because a tool exists, doesn't mean it's good (or better than what people are accustomed to) or that everyone must use it. Do you think everyone should use Vim on Linux too?
- SixSigma 13y agoit is so you can type grep -n ^functionname *.c and get the line that starts the definition
- copergi 13y agoAre you sure you aren't confusing it with K&R style with the argument names on a different line? That would indicate old code. Having the return type on a different line is incredibly common, virtually every C project with decent code uses it.
- saucetenuto 13y agoI dunno, a few of them seem hard to justify. The one on line 475 could just be an "else" branch, frex, and the ones in the loop on 327 could as easily be continues.
- __david__ 13y agoOnly one goto in the loop could be a "continue", the one in the nested loop cannot. The one that could be is most likely a goto just for consistency.
- mjibson 13y agoWhen the full video of the talk comes out, you will see that Russ agrees with you. He lists the types of uses of goto. Various are used to make loops or elses, and he says those should not have occurred.
- simias 13y agoI would be curious to hear the justification behind the implementation of angryrealloc, the "goto ok" is strictly equivalent to a "continue" as far as I know. Maybe it triggers an optimization with a certain compiler.
- chc 13y agoIt's to continue the outer loop from the inner loop.
- daeken 13y agoI'm not surprised to see them in a compiler. When you're parsing and want to treat it as a big state machine, gotos are your best friend.
- bakul 13y agoExcept in languages with tail recursion such as Scheme! A state ends with a call to the next state instead of a goto next state.
- clarry 13y agoEncoding state implicitly in control flow tends to give you nicer and more natural code. A big state machine implemented with gotos can be tough to read if it's also a parser (which may need to build a tree, recurse, etc.). A small hand-rolled lexer might be reasonable to implement with goto. Although I would prefer to enumerate the states and use a switch. If you're writing a recursive descent parser for C while keeping minimal lookahead, I can think of a place or two where goto might really help. One is to deal with casts, compound literals and subexpressions. They all begin with a left-parenthesis, so you can't tell what you're dealing with until a bit further. Since these all appear in the parsing of simple expressions (identifiers, constants, unary operators), the code can go in one function and you can jump to the right place with goto as soon as you know what you are dealing with. I did not look in the Go code but C programmers mostly use goto for error paths.
- awda 13y agoAs others have pointed out, this is actually idiomatic C. You have a portion of your function below a label which is "clean up everything and return this variable (usually error status)." Then at any point where you have an error, you goto that label and everything is released and the error gets returned. It's sort of a manual 'defer' pattern. "goto considered harmful" is taken out of context and bemoaned mostly by people unfamiliar with idiomatic C, I think. (Edit: sorry, I mean just for C. For other languages, e.g. Go, there may be more appropriate patterns like the 'defer' keyword.)
- im3w1l 13y agoI saw one goto that could cleanly be replaced with an else (goto fp). I don't think the authors were very goto-averse.
- coldtea 13y ago>but for something written in the last couple of years to have over a thousand of them is very surprising Hardly surprising. Gotos will be found by the hundrends or thousands in C projects like compilers, kernels etc. It's used for localized consolidated error handling, but also for stuff like parsing code (bison generates tons of gotos IIRC), state machines, etc. If anything it's the old "Goto statement considered harmful" that's a little too naive.
- copergi 13y ago>If anything it's the old "Goto statement considered harmful" that's a little too naive. No, people who didn't read it and just repeat the title without knowing what he was talking about may be too naive, but the original point was not.