guy@rlgvax.UUCP (Guy Harris) (01/10/85)
> Please don't attribute to me something I didn't say. I was not advocating > the elimination of goto's from C, but felt the put-down of the idea of break > <label> might not have been well thought out. But what Ron was saying was that if you don't eliminate "goto", "break <label>" just amounts to "semantic sugar" for "goto <label>"; if you want to discourage people from using "goto" you can just put #define breakloop goto or something like it in a header file. Putting in a "break" statement which acts exactly like "goto" but which is only accepted by the compiler in certain contexts doesn't really add anything to the power of the language. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
mjl@ritcv.UUCP (Mike Lutz) (01/11/85)
> ... Putting in a "break" statement which > acts exactly like "goto" but which is only accepted by the compiler in certain > contexts doesn't really add anything to the power of the language. > > Guy Harris I disagree with Guy on this one (exceedingly dangerous, if you know what I mean, and I think you do :-). If indeed the break <label> is added so that a) the <label> must be associated with a control construct in which the break is nested and b) causes execution to start with the first statement following this construct, then indeed it is different from (and, I argue, a useful alternative to) goto <label>. Guy is right - break <label> does not extend the power of the language; if anything, it limits it (or, better yet, controls it). The altered semantics *are* important. Sure, the documentation effects can be achieved by strict adherence to programming conventions and the use of a #define like the one Guy proposed. However, the error detection possibilities are every bit as important (I vaguely remember making an error long ago), and the limited form of goto can turn difficult to diagnose run-time errors into compile-time errors. All of this ignores, of course, any assessment of the problems of incorporating this facility in C relative to its worth. I've no illusions about the difficulty, especially when you realize that all labels are potential targets of a goto but some are also possible referents of the new break. But I was addressing the absolute utility of the construct, rather than its relative utility when considering the engineering problems of such a retrofit. -- Mike Lutz Rochester Institute of Technology, Rochester NY UUCP: {allegra,seismo}!rochester!ritcv!mjl CSNET: mjl%rit@csnet-relay.ARPA
Doug Gwyn (VLD/VMB) <gwyn@Brl-Vld.ARPA> (01/11/85)
I really think the discussion of "goto" in C is overblown. I just grepped through over 6,000 lines of production C code and found one instance of goto used as an EOF exception escape and 7 instances (in the same module) of gotos to a common error return. Not a single goto for any other purpose, including multi-level breaks. I would argue that this code exhibits why "goto" can be useful and that the "dangerous" uses of it can be totally avoided. Perhaps programmer education is more important than changing the language.
mat@hou4b.UUCP (Mark Terribile) (01/11/85)
>But what Ron was saying was that if you don't eliminate "goto", >"break <label>" >just amounts to "semantic sugar" for "goto <label>"; >if you want to discourage people from using "goto" you can just . . . Not quite. You see, if you follow out this philosophy, we can do away with for(;;) and while() and the else in if()-else ... and compound statements too. An upholsterer's tack hammer is no more powerful than a 15-lb maul. Why use the tack hammer? Because it is suited to the job. More specifically, it lets you put the force you need where you need it without scattering that force everywhere else. The labelled break allow you to get out of (i.e. go to just below) a loop without making it possible to get there from anywhere else. Very important. Viewed differently, the labelled break is the addition of a (presumably) needed capability to the thing that needs it (the loop and switch statements) without making the remainder of the program unsafe. -- from Mole End Mark Terribile (scrape .. dig ) hou4b!mat ,.. .,, ,,, ..,***_*.
MLY.G.SHADES%MIT-OZ@MIT-MC.ARPA (01/12/85)
> Perhaps programmer education is more important than changing the language.
at last somebody who understands. it's the programmer who writes the
damn code not the language compiler.
shades@mit-oz
Doug Gwyn (VLD/VMB) <gwyn@Brl-Vld.ARPA> (01/12/85)
People keep hoping for the magic panacea that will ensure automatic correctness of their programs. Last year it was Ada; this year it is knowledge-based program writing systems; next year it will be something else. I keep seeing the same ideas attempted over and over as the years go by. The one idea that works, to think clearly and carefully, has not found much favor.
guy@rlgvax.UUCP (Guy Harris) (01/13/85)
> Not quite. You see, if you follow out this philosophy, we can do away with > for(;;) and while() and the else in if()-else ... and compound statements > too. Yes, but while (<condition>) { ... } is easier to read and write than loop: if (!<condition>) goto endofloop; ... goto loop; while one "ed" command, or one #define, can turn while (<condition>) { ... breakloop label; ... } label: into its "goto" equivalent. (Putting the label at the beginning of the loop would make that harder, but it would also make it harder for the reader to find the point that the "breakloop" goes to. > The labelled break allow you to get out of (i.e. go to just below) a loop > without making it possible to get there from anywhere else. Except for one problem: nobody's proposed deleting "goto" from the C language (and anybody who proposes it should personally have to rewrite every program that uses it safely). As such, C *will* let you get anywhere from anywhere else (within a function body, at least) even with the addition of the "break <label>" construct. If we're designing a *new* language, we might consider fancier "break" statements and no "goto" (although even "break" and "continue" can impair the readability of a program). Since C already has a "goto", though, and it's impractical to eliminate it, I don't think "break <label>": 1) makes the language easier to write in 2) makes it easier to read programs 3) makes it easier to verify programs 4) makes it easier to optimize programs I presume that any flowgraph that for a program written with "safe" "goto"s can be rewritten either with "break <label>" and "continue <label>", or by node splitting (i.e., where "goto" is used as a way of folding code). This is probably close to a formal statement of my notion of "safe" "goto"s, and probably close to most other people's notion as well. If so, you can formally eliminate "goto"s from programs, so the only question that comes up is whether the informal aspects of readability and writability are affected by the addition of "break <label>". I don't think it's affected enough to make it worth the trouble of adding "break <label>" to the language. As I've said, even unlabelled "break" and "continue" statements can impair readability; it's harder to find the end of a loop when examining its innards in detail than when looking at the loop as a whole, so that it is less obvious what the flow of control is when looking at the "break" in while (<condition>) { ... if (<condition 2>) break; ... } then when looking at the "while" loop as a whole. (I.e., it's more obvious that control flows from the code before the closing "}" to the condition test on the "while" line than it is that control flows from the "break" statement to the code after the closing "}".) I would still use a "break" in this case, out of habit and out of a partially-superstitious desire to avoid a "goto", even though putting in a label might make it easier to see where the "goto" goes to; also because it means I don't have to invent a name for the label. Putting in a "break <label>", however, means I have to invent a label. And if the label goes at the beginning of the loop, rather than the end, you have to search for the label and then search for the end of the loop to figure out where it goes. This is becoming a problem in the psychology of programming; does anybody have any hard evidence for or against the proposition that labelled breaks - of either kind - make it easier to program? If not, we're all trading anecdotal evidence, and the horse's corpse is beginning to look a bit messy... Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
Tony Li <Tli@Usc-Eclb> (01/13/85)
From: Doug Gwyn (VLD/VMB) <gwyn at BRL-VLD.ARPA> People keep hoping for the magic panacea that will ensure automatic correctness of their programs. Last year it was Ada; this year it is knowledge-based program writing systems; next year it will be something else. I keep seeing the same ideas attempted over and over as the years go by. The one idea that works, to think clearly and carefully, has not found much favor. It has not found much favor because it does not work well. Consider the lifecycle of an average software package. Currently, for *ANY* software package, you should expect to spend at least half of your budget on maintenance. The hope is that the development of a automatic correct program generator would help to eliminate much of this maintenance cost. Cheers, Tony ;-)
MLY.G.SHADES%MIT-OZ@MIT-MC.ARPA (01/13/85)
agreed that a significant amount of all software production is spent doing simple maintenance i still agree with doug gwyn that clear thinking (i.e. good old common sense) would improve correctness, maintainability, and reduce cost more than compiler enforced rules. something that i have noticed out in the "real" world is that the more complex the language rules, no matter how rigidly enforced, the more drastic the increase in the time necessary for the 'average' (six month matchbook cover) programmer to produce even the simplest of programs (unfortunately these are also the ones least likely to use their common sense). it cuts both ways. rigidity and higher costs in development or looseness and higher maintenance costs. one major problem that i commonly see is that the more junior the programmer the more likely he/she/it will be doing the maintenance. this is a serious problem. the person with the least(!) experience is given the job where that person can do the most damage. (sigh) anyway when it gets down to brass tacks my objection to break label is mainly on the grounds that enforcing the construct properly would be adding a grievous burden upon the compiler. if the label is placed before the block that it escapes the compiler must generate two internal labels for that label, one for the break and one for a possible goto. this is of course only a hazard on smaller machines supporting small symbol tables but it still is an unecessary
Tony Li <Tli@Usc-Eclb> (01/14/85)
Whoa! I'm not out to automate current design practices. I'm much more interested in providing a NEW design methodology whereby the compiler (or some other entity - like lint for C) goes through and either (1) proves your program correct or (2) derives a provably correct program from a proof of an algorimth. Work is currently being done on both these topics on a very small scale, and things look quite promising except for the fact that doing these things take mega-cycles. Once we know enough to where we could make things efficient, this should greatly simplify the software design process. Ultimately, it might be possible to have the designer just state the goals, and let the system generate all of the code, e.g. "Sort these numbers, and write them to tape as an ANSI file FOO.BAR". The heuristics are involved when we try to generate "good" code for a specification that has a little leeway. Since there are lots of possible implementations, and we don't have the opportunity to look at all of them, we need a heuristic to help decide the implementation. So actually, I guess that I'm in favor of giving the programmer a lot of assistance in 'thinking logically and clearly'. Currently, this is a tough proposition, and is done by a very few people. I'm hoping that this would mean that new programmers would have to learn very few new rules (mostly Boolean logic - that's not unreasonable, is it? ;-). And with that, you could dispose of a lot of nitpicking rules that we have now. [End of digression, back to reality] As to break <label>, I have mixed feelings. Yes, it's a cleaner feature than a goto. Unfortunately it's not trivial to implement, and it's a new feature, which means that it would wind up in C from now to eternity, along with 'goto'. I'm not sure that the gain makes up for the burden on the language design. Cheers, Tony ;-)
MLY.G.SHADES%MIT-OZ@MIT-MC.ARPA (01/15/85)
when you but in that form (new design methodology) i tend to agree. proving correctness would be nice but we still end up with the problem of providing possibly deleterious additions to an existing language (break <label>). the c compiler that i use at home is decus c on a small(!!) 11 and at work it is the honeywell mod400/dps 6 c compiler basically derived from unix's, i also use the pcc compiler for tops-20 here at oz. all of them are excessively slow and in the case of my home machine limited in symbol table size. anything that degrades performance in this case without being a significant improvment to the language as a whole would be fiercely resented. sorry about the incomplete previous message i sent that accidentally but since the discussion has passed on i will not finish it.
rpw3@redwood.UUCP (Rob Warnock) (01/15/85)
+--------------- | People keep hoping for the magic panacea that will ensure automatic | correctness of their programs... +--------------- Quite so, Doug. Also see the current? issue of "Whole Earth Review", on the theme of "Computer As Panacea: All Panaceas Turn To Poison". +--------------- | ... The one idea that works, to think clearly | and carefully, has not found much favor. +--------------- There is a reason. It is painful to do so until one has been trained (disciplined) enough so that the results of NOT doing so are more painful than the thinking. The training takes a long time. It too is painful. There are not many teachers/mentors/gurus/old-timers around who can help us through the rough stages, and doing so on one's own is not likely (though possible). The sage advice printed in books pales against your bosses' demands for "More!" and "Now!". It requires an exceptionally hospitable environment (such as being a support staff member in a graduate or post-graduate research atmosphere). I remember the first time I seriously tried to write a program that would be "perfect", that is, to compile and execute correctly the first time it was submitted to the system. (I had gotten all excited reading Djikstra or somebody, and had this wild hair about "zero defect" programming.) I was just switching from MACRO-10 (the assembler) to BLISS-10 (which has no "goto") for doing systems programming, and was writing a "stdio"-like I/O package. (BLISS-36 now comes with "EZIO", but it didn't exist then.) The specification was fairly simple. I wanted the program: MODULE TEST = BEGIN REQUIRE IOX.REQ; ! These days we say "#include <stdio>" LOCAL C; WHILE (C = GETC()) NEQ IOX_EOF DO PUTC(.C); END ELUDOM to give the user a standard prompt (using SCAN/WILD, for you TOPS-10 folk), accept a command string of *OFILE=IFILE1,IFILE2,... and do "sort of the same as" the UNIX command "cat ifile1 ifile2 ... >ofile". The exercise in fact succeeded, but it was *P*A*I*N*F*U*L*. (And I don't just mean giving up the "goto"!) The only way I managed to do it was to write the entire program on paper, in a notebook, saving all versions and notes and scratchings, and REWRITING each module in a clean form for each step of refinement or backup. (Yes, I had to back up a lot.) A couple of times I started typing it in, but realized there were pieces missing, and went back to the notebook. That was possibly the most painful part -- staying away from the machine. But it paid off. When finally typed in (and printed out BEFORE compiling and desk-checked and corrected), it compiled and ran. I am sorry to say that many times in the years since I have allowed myself to become seduced again by the very addictive nature of working "on line", sometimes to the extent that I could not consider working if the computer was "down" (even when what I had to do could be done on paper!). But sometimes when the project was just too big for me to hold in my head or on the 25 lines of the screen, or when I just HAD to get it done right and on time, I would revert to the "primitive" methods of pencil and paper, of "design before code". I feel I have learned several lessons: #1: "Zero defect" development of software is possible, but it requires a severe discipline in how one works. #2: Even for people who know #1, and who understand what it implies, it is never easy. Constant little temptations or pressures arise to try to shortcut the necessary steps. It never gets any easier. The whole environment must support the effort. #3: Knowing #2, the only way we will do it is if we realize the cost of NOT doing it (bugs we'll never find, slipped schedules, cost overruns, and maintenance headaches). #4: Most software development organizations ("Management") are not willing to face #3 (see any book on Quality Control), so since #2 is still true, "zero defects" becomes impossible, or at least unlikely. Even individuals who understand #1, #2, and #3 find difficulty in consistently applying their understanding on problems that seem "too small" or "not worth it" (i.e., we ignore the cost to ourselves in getting sloppy in our discipline). #5: Both large organizations and individuals tend to severely underestimate the scope of tasks, thus reinforcing #4. How does this concern net.lang.c? In my experience, C is "good enough" as it is. The above considerations far outweigh the minor wrinkles the net has seen discussed recently (e.g. how to initailize unions, "goto" versus "break" versus "leave"). Yes, C can be tuned a bit, and people would benefit from it, I suppose. (I favor the "leave <labelled-block>", myself, but frankly I don't recall having ever used a "goto" in C, for ANY purpose, so who am I to say?) But to some extent, such discussions of the effect of programming constructs on program correctness are similar to discussing the effect of the color of automobile dash panel indicators on traffic safety while driving 90 miles an hour in the rain, with one hand on the wheel, drinking whiskey, with the radio turned up to deafening, your headlights off, and no seatbelt. (While the sarcasm of the previous sentence may be a bit heavy, consider the New England pediatrician who completely gave up his medical practice of many years and went to work lobbying for infant car seats. He had looked up one day and discovered that preventible auto-accident injury killed more of his young patients than ALL other causes COMBINED, including disease and all non-auto accidents.) +--------------- | ... The one idea that works, to think clearly | and carefully, has not found much favor. +--------------- Rob Warnock Systems Architecture Consultant UUCP: {ihnp4,ucbvax!dual}!fortune!redwood!rpw3 DDD: (415)572-2607 USPS: 510 Trinidad Lane, Foster City, CA 94404
henry@utzoo.UUCP (Henry Spencer) (01/15/85)
> People keep hoping for the magic panacea that will ensure automatic > correctness of their programs. Last year it was Ada; this year it > is knowledge-based program writing systems; next year it will > be something else. I keep seeing the same ideas attempted over and > over as the years go by. The one idea that works, to think clearly > and carefully, has not found much favor. > > It has not found much favor because it does not work well. Consider > the lifecycle of an average software package. Currently, for *ANY* > software package, you should expect to spend at least half of your > budget on maintenance. I fail to see how this contradicts anything Doug said. Unless, of course, you add an implicit "...and your maintenance programmers will be dolts, incapable of clear and careful thought"! -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
ron@brl-tgr.ARPA (Ron Natalie <ron>) (01/15/85)
> All of this ignores, of course, any assessment of the problems of > incorporating this facility in C relative to its worth. I've no > illusions about the difficulty, especially when you realize that all > labels are potential targets of a goto but some are also possible > referents of the new break. But I was addressing the absolute utility > of the construct, rather than its relative utility when considering > the engineering problems of such a retrofit. > -- Agreed. I'm not saying break-to-label isn't a good thing for some language to have. There's a lot of things we could put into languages if we were starting over. What I'm arguing against is making frivolous changes to an existing language. So far nearly all of the proposed extensions that the committe has been proposing, do not change the language when it can be avoided. If we trully want to be structured we'd get rid of "break" and "goto" -Ron
ron@brl-tgr.ARPA (Ron Natalie <ron>) (01/15/85)
> I really think the discussion of "goto" in C is overblown. > I just grepped through over 6,000 lines of production C code > and found one instance of goto used as an EOF exception escape > and 7 instances (in the same module) of gotos to a common error > return. Not a single goto for any other purpose, including > multi-level breaks. I would argue that this code exhibits > why "goto" can be useful and that the "dangerous" uses of it > can be totally avoided. Perhaps programmer education is more > important than changing the language. Yes, this is an indication that the reason most good programmers place non-structured constructs in their code is to avoid code duplication. -Ron
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (01/16/85)
> ... this is an indication that the reason most good programmers > place non-structured constructs in their code is to avoid code > duplication. Or to handle errors and exceptions that cannot be reasonably treated by the main program logic. The alternative often is to ignore these, with loss of robustness, or to carry around lots of silly state flags to be tested in loop conditions.