Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!ll-xn!mit-eddie!bloom-beacon!gatech!uflorida!novavax!proxftl!bill From: bill@proxftl.UUCP (T. William Wells) Newsgroups: comp.lang.c Subject: Re: gotos Summary: talking about gotos is fruitless Message-ID: <197@proxftl.UUCP> Date: 19 May 88 19:52:54 GMT References: <1988Apr8.183815.3187@utzoo.uucp>, <449@goofy.megatest.UUCP> <528@wsccs.UUCP> Organization: Proximity Technology, Ft. Lauderdale Lines: 128 Under ordinary circumstances, there is exactly one place where a human C coder might use a goto. This is to implement multi-level breaks and continues. I say this, having managed (and written huge chunks of) a 17,000 line software system (and that is only the part we sell, and does not include development tools). I have programmed in C for six years now and have NEVER used a goto. We have uncounted megabytes of C code written in-house. None of it (to my knowledge) contains a goto. The closest thing we have to a goto is setjmp/longjmp, used to implement a multi-level return (and that is a recent change, one whose contemplation caused much debate). With that aside, let me explain why the goto discussion is really fruitless. People have observed that gotos are used in a lot of bad code. From this it is concluded that gotos are bad. This is really bad logic. Try this: programmers have been observed to write bad code; therefore, programmers are bad! THERE IS NOTHING WRONG WITH GOTO. (And how do I reconcile with my mouthing off above? Wait and see...) The thing that is screwed up is the control structures being implemented with the gotos. The whole point of the structured programming debate is this: every program has a control structure; some of these control structures are better than others. Whether you use gotos or some other language feature to implement the control structure does not change what the control structure is nor does it affect the goodness of the control structure. The quality of your program is strongly influenced by the quality of its control structures. Furthermore, you want that control structure to be obvious and understandable to the reader of the program. This implies that you use language features that make your use of a control structure obvious. So, the first question should be: what are the good control structures? The second question should be: given a particular language, how should the control structures be implemented? Ok, so what makes a control structure good? Well, the basic answers are: a control structure is good if it is 1) appropriate to solving programming problems. 2) easy to write. 3) easy to understand. 4) easy to maintain. 5) ... add your own as long as they do not contradict the above There are obviously lots of control structures that meet these requirements and you do not have to use all of them. In fact, you should pick a set of those which are most appropriate for your programming environment and use them. This set should be, in some sense, a minimum one; for example, if you have two control structures which can accomplish the same thing, but one is easier to use than the other (for you), pick the easier one and forget the other. All other things being equal, a smaller number of control structures helps make your program easier to understand. Now, I hope my claim about our C programs is understandable. But if not, here is what it amounts to: I have chosen a set of control structures which is appropriate to programming in C, for the kind of programming tasks that I do. It happens that, while my set of control structures includes multi-level breaks and continues (which would be implemented with a goto), I have never had need of one. Given the amount of code I write, it seems to me that one might never need to use an explicit goto in C code. Now that I think of it, here is a reason to avoid naked gotos in C code: for all other constructs, the control structure being implemented is obvious from the keywords employed. This is not true for goto. Therefore, supposing that you have found a control structure that you have to implement using gotos in C, you should dress the goto up. As an example, suppose that you are using the state machine control structure. I normally code it as: state = STATE_INIT; while (state != STATE_DONE) { switch (state) { case STATE_INIT: ... } } However, this is not the most efficient way to do it. You could also implement it as: /* Wherever you see the macros state and nextstate being used, you will be seeing a state machine. The state macro defines the start of a state. The nextstate macro causes a transfer of control to another state of the same machine. A state machine starts at a #define of statepref and ends with state(DONE). */ #define dummy(x) x #define state(x) dummy(statepref)x #define nextstate(x) goto dummy(statepref)x #ifdef statepref #undef statepref #endif #define statepref STATE_ state(INIT): ... code for this state nextstate(DONE); ... more states with the appropriate code state(DONE): ... code after the state machine (N.B. I am aware that not all preprocessors will do what I want here; for real portability, you would explicitly write the prefixes. Also, this method fails for nested state machines, something I have occasionally had need of.) Some of you will no doubt be thinking: but why should I go to all this effort when I could just use the goto directly? Well, if this was all you did with goto, I don't really see any reason why not (but I do think your program should include a comment saying that you use goto for state machines and describes how you structure it). If, however, you have more than one way of using goto, you should clothe the gotos somehow so that the reader of the program knows what control structure your goto belongs to. (After all, a while is just a disguised goto :-)