schow@bnr-public.uucp (Stanley Chow) (03/01/89)
In article <881@sceard.UUCP> mrm@sceard.UUCP (M.R.Murphy) writes: [Mike Murphy tells us about a list of programming errors that he has kept over the last ten years and asks for additions. SC] > > 1) Is the argument count correct? > 2) Is the spelling correct? > 3) Is the argment type correct? > 4) Is the variable initialized correctly? > 5) Do "ends" match "do"s? > 6) Is the correct register used? > 7) Is a previous equate, using, or define in effect? > 8) Is the level of indirectness correct? > 9) Are the defaults correct? > 10) Is the array large enough to hold the data? > 11) Is the index out of range? > 12) Is reentrancy, reusability, refreshability preserved? > 13) Did you let something go by that you can't explain? Fix it now. > 14) Does the program have anything remotely to do with the requirement > for the program? > 15) Did you start to code before thinking? > 16) Did you read the manual? > >--- >Mike Murphy Sceard Systems, Inc. 544 South Pacific St. San Marcos, CA 92069 >mrm@sceard.UUCP {hp-sdd,nosc,ucsd}!sceard!mrm +1 619 471 0655 I like to ask people a different question (i.e., cross posting to comp.lang.misc) based on this (possiblely expanded list). How many of these error can be (are) prevented/encouraged by the language (implementation and specification), O/S, developement environment that you use? How much cost saving (time & money) could be achived if an environment prevents all of these problems? What problems would remain? Since the religous war potential of this is very high, I suggest everyone refrain from commenting on C or Ada. Comments on why certain class of errors is a neccesary evil in a particular language/application should be accompanied by justification instead of rhetoric. Please, if you felt "real programmers don't make mistakes", feel free to start a religous war of your own; don't hide it under my Subject line. Stanley Chow ..!utgpu!bnr-vpa!bnr-fos!schow%bnr-public (613) 763-2831 P.S. I would volunteer to collect comment and summerize but our mailer is quirky and unreliable (as least for me) so I better not. Since I havn't said anything, and I havn't been paid for saying anything anyway, I don't think anyone will claim to be represented by any of this.
sommar@enea.se (Erland Sommarskog) (03/03/89)
Stanley Chow (schow@bnr-public.UUCP) writes: > How many of these error can be (are) prevented/encouraged by the > language (implementation and specification), O/S, developement > environment that you use? > > How much cost saving (time & money) could be achived if an environment > prevents all of these problems? What problems would remain? >M.R.Murphy (mrm@sceard.UUCP) writes: >> 1) Is the argument count correct? Can occur with languages with a weak module concept like C and Fortran. But are also likely to occur with routines with variable parameter lists like for instance VMS system calls. Gain: Variable parameter lists gives flexibility. Loss: Harder to detect mistakes. More likely that error causes a crash in a live system. >> 2) Is the spelling correct? Occurs with totally interpreted languages like DCL or MUMPS. Gain: Enormous strength for referencing by string manipulation. Loss: Unbearable for somewhat big programs. I've just condluded 300 lines of DCL what would have been longer in a compiled langauges. But to test it takes longer time. >> 3) Is the argment type correct? Occurs with untyped or weakly typed langauges like C, Pascal and Lisp(?). Gain: Higher flexibility when you really have multi-type arguments. (Not with Pascal.) In many applications no gain at all. Loss: Errors are detected later and will be more expensive. >> 4) Is the variable initialized correctly? Occurs with most langauges. Some langauges (e.g. Eiffel, Simula) defines intial values which saves when the correct initial values is the same as the one of the langauges. Also, it gives the erroneous program as a less random appearance. (Works sometimes, sometimes not.) Although assert statements and similar can help, this is mainly a programmer issue. >> 5) Do "ends" match "do"s? Occurs only in interactive langauges. Simple but fatal errors you don't want be afraid to have in your 200000-line system. >> 6) Is the correct register used? Seems like an assembler-only problem. >> 7) Is a previous equate, using, or define in effect? Given as C problem, but similar can occur in any block-oriented language with a WITH or USE statment. Often convenient for short notation. Problem when over-used. >> 8) Is the level of indirectness correct? Sounds like something that would happen with assembler or maybe C. And, yeah, DCL too. But the levels should never be that many one one step. More like a programmer issue. >> 11) Is the index out of range? Any langauge that allows you to turn off index checks, which means all. Gain is better performance Loss is strange-behaving programs. >> 12) Is reentrancy, reusability, refreshability preserved? Reusabililty at least requires flexibility and modularity. Pascal is a real loser here. Ada and Eiffel and winners. >> 13) Did you let something go by that you can't explain? Fix it now. >> 14) Does the program have anything remotely to do with the requirement >> for the program? >> 15) Did you start to code before thinking? >> 16) Did you read the manual? Programmer issues to most part. Important nevertheless. -- Erland Sommarskog ENEA Data, Stockholm This signature is not to be quoted. sommar@enea.se
holt@turing.toronto.edu (Ric Holt) (03/04/89)
I think the following long question deserves to be clarified, as it mixes up several concepts that we as Computer Scientists should understand: *In article <313@bnr-fos.UUCP> schow@bnr-public.UUCP (Stanley Chow) writes: *>In article <881@sceard.UUCP> mrm@sceard.UUCP (M.R.Murphy) writes: *> [Mike Murphy tells us about a list of programming errors that he has *> kept over the last ten years and asks for additions. SC] *>> *>> 1) Is the argument count correct? *>> 2) Is the spelling correct? *>> 3) Is the argment type correct? *>> 4) Is the variable initialized correctly? *>> 5) Do "ends" match "do"s? *>> 6) Is the correct register used? *>> 7) Is a previous equate, using, or define in effect? *>> 8) Is the level of indirectness correct? *>> 9) Are the defaults correct? *>> 10) Is the array large enough to hold the data? *>> 11) Is the index out of range? *>> 12) Is reentrancy, reusability, refreshability preserved? *>> 13) Did you let something go by that you can't explain? Fix it now. *>> 14) Does the program have anything remotely to do with the requirement *>> for the program? *>> 15) Did you start to code before thinking? *>> 16) Did you read the manual? SYNTAX, SEMANTICS AND FAITHFUL EXECUTION Before going further, we should ask: What characterizes a language? We have to understand that a language defines a SYNTAX (what strings are considered to be programs) and a SEMANTICS (what do programs mean or do). A great deal of confusion arises from the fact that one of the most popular languages, C, has a muddled semantics (we're not sure what pointers can do and mean; we're not sure what variable numbers of parameters do and mean; etc). This muddle shouldn't detract us from the fact that languages such as Turing have exactly specified semantics (it is mathematically clear what every construct does, independent of any implementation). OK, with that behind us, we can ask: does the implementation really follow the semantics. Before you say "of course", ask questions like: what are the semantics of dangling pointers, overflows, out of range subscripts, etc. The concept of FAITHFUL EXECUTION is defined to mean: the implementation is required to follow the semantics exactly, or else to halt and notify the user of the failure. With the default checking enabled, Turing gives you faithful execution, stopping and giving you an error message if ever anything occurs that is outside of the language's explicit semantics. DIRT AND DANGER Now let's go on to DIRTY language features, which by definition have their meaning determined by underlying implementation details, such as what's in a particular register (as opposed to CLEAN features, which are mathematically defined). Dirty features can be DANGEROUS, meaning they can cause remote corruption (eg, emitting assembly language by user control can cause arbitrary corruption that the language implementation has have almost no control over). The Turing Plus language introduces dirty features, in a controlled fashion, because these are needed for certain applications. The problem with dirt and danger is they put a tremendous responsibility on the programer, which would otherwise be born by the language implementation. My guess is that C's degree of dirt and danger costs 50% in terms of programmer productivity compared with programming in a faithful language. SPECIFICATION, CORRECTNESS, STYLE AND METHODOLOGY Add to these the concepts of SPECIFICATION (what's a program supposed to do) and CORRECTION (does the program do it) and STYLE (can you easily read the program and figure out how the program does it). METHODOLOLGY means do you know how to get from a specification to a correct program. In languages that are generally like Turing (Ada, Modula, Pascal, maybe C, etc) we have: SYNTAX - enforced by compiler SEMANTICS - produced by compiler and runtime support FAITHFULNESS - enforced by generated code and runtime support (depending on language) STYLE - depends on skill and patience of programmer CORRECTNESS - depends on programmer and methodology used Now, the questions are categorized using these concepts: 1) Is the argument count correct? SYNTAX 2) Is the spelling correct? SYNTAX 3) Is the argment type correct? SYNTAX 4) Is the variable initialized correctly? FAITHFUL, CORRECTNESS 5) Do "ends" match "do"s? SYNTAX 6) Is the correct register used? DIRTY 7) Is a previous equate, using, or define in effect? SEMANTICS (DIRTY?) 8) Is the level of indirectness correct? SEMANTICS, FAITHFUL 9) Are the defaults correct? SEMANTICS, FAITHFUL, CORRECTNESS 10) Is the array large enough to hold the data? FAITHFUL, CORRECTNESS 11) Is the index out of range? FAITHFUL, CORRECTNESS 12) Is reentrancy, reusability, refreshability preserved? SEMANTICS etc 13) Did you let something go by that you can't explain? Fix it now. CORRECTNESS, though language design helps tremendously to avoid shoot-in-the- foot-features. 14) Does the program have anything remotely to do with the requirement for the program? CORRECTNESS 15) Did you start to code before thinking? METHODOLOGY 16) Did you read the manual? METHODOLGY The above categorization of questions shows how the corresponding questions are handled in Turing-like languages. HOW DOES A LANGUAGE HELP? A language designed for productivity and reliability maximizes the degree to which problems are eliminated or detected by the computer, as opposed to by raw programmer acumen. As the language becomes less faithful and "dirtier" (Turing to Pascal to Turing Plus to C to assembler) you sacrifice productivity and reliability (as a rule). Similarly, as the language becomes more interpretive and dynamic in nature (Turing to Basic to APL to LISP) you get less syntactic help from the computer, as restrictions designed to help you are put off to run time or eliminated altogether. Ric Holt
elliott@hound.UUCP (E.GORELICK) (03/05/89)
This has happened more than once and the program will often compile and run especially if it is an error trapping routine. 17) Did you comment out part of your code? You feel really stupid when you find the error. elliott
hollombe@ttidca.TTI.COM (The Polymath) (03/07/89)
In article <2950@hound.UUCP> elliott@hound.UUCP (E.GORELICK) writes: }This has happened more than once and the program will often compile }and run especially if it is an error trapping routine. } }17) Did you comment out part of your code? } }You feel really stupid when you find the error. This is the reason I delimit all comments line by line and have fought to get that practice included in several coding standards. C example: /* This comment is */ /* delimited line */ /* by line. */ /* This is the way too many other people do it. */ The above example is a trivial oversimplification that doesn't show how the second form can cause problems. I've seen several pages of comments, including some that looked remarkably like source code, delimited with a single set of /* */. Also, when deliberately commenting out source code, if you do it line by line, it makes it much easier to find when scanning through the code and makes it less easy to forget or not notice that it's been commented out. (A better technique for this is to use #ifdef BLAH #endif, where BLAH is not defined. #ifdef BLAH is harder to miss than /*). I've never accidentally commented out source code since following this practice. (I've never done it anyway, but better safe than sorry). -- The Polymath (aka: Jerry Hollombe, hollombe@ttidca.tti.com) Illegitimati Nil Citicorp(+)TTI Carborundum 3100 Ocean Park Blvd. (213) 452-9191, x2483 Santa Monica, CA 90405 {csun|philabs|psivax}!ttidca!hollombe
bill@twwells.uucp (T. William Wells) (03/09/89)
In article <3998@ttidca.TTI.COM> hollombe@ttidcb.tti.com (The Polymath) writes:
: This is the reason I delimit all comments line by line and have fought
: to get that practice included in several coding standards.
:
: C example:
:
: /* This comment is */
: /* delimited line */
: /* by line. */
:
: /*
: This is the way
: too many other
: people do it.
: */
:
: The above example is a trivial oversimplification that doesn't show how
: the second form can cause problems. I've seen several pages of comments,
: including some that looked remarkably like source code, delimited with a
: single set of /* */.
There's a much better way of dealing with this: have a lint complain
when a /* occurs in a comment or a /* is not terminated. Such a
program is very short, less than a hundred lines (write it as a FSM),
and will catch all errors of this type. Add it to your toolkit and
stop worrying about this problem. No, I don't have such a program
handy; I typically don't make this particular mistake and so I have no
need for one. (I have my own favorite mistakes. :-)
(I know of two compilers that actually do this check and deliver a
warning when a comment is found within a comment.)
The line-by-line style is more difficult to read (one must mentally
subtract the /* */ on each line), more difficult to maintain (one
must remove the /* */ before reformatting text [don't say anything
about emacs, please; all the world's not emacs]), and more difficult
to write (one has to put the pesky things in, often after one has
finished writing the comment). Not only that, it doesn't really
solve the problem; only discipline will solve that problem, absent an
appopriate tool. Why use this comment style when there is a simple
tool that eliminates the problem in better ones?
One final note: this is my opinion, I offer my solution to the
problem solely as information with which to aid in choosing a comment
style. I *will not* debate this. I suggest that you don't debate it
either; such debates are rarely fruitful. Just make up your own mind,
pick a consistent style, and adhere to it.
---
Bill
{ uunet | novavax } !twwells!bill
(BTW, I'm going to be looking for a new job sometime in the next
few months. If you know of a good one, do send me e-mail.)
nick@lfcs.ed.ac.uk (Nick Rothwell) (03/09/89)
My favourite of the "Oh, look, it's commented out" problems is the following one I ran into in a 1st year's PASCAL program many years ago; it had to print out a pattern of stars, or somesuch: PROGRAM .... ... FOR i := 1 TO 50 DO Write(*); ... ...lots more code... ... FOR i := 1 TO 50 DO Write(*); ... END. The program was perfectly legal; the student couldn't understand why on earth large chunks of his program were being mysteriously ignored. Nick. -- Nick Rothwell, Laboratory for Foundations of Computer Science, Edinburgh. nick@lfcs.ed.ac.uk <Atlantic Ocean>!mcvax!ukc!lfcs!nick ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ...while the builders of the cages sleep with bullets, bars and stone, they do not see your road to freedom that you build with flesh and bone.
crooks@crooks.crooks.ingr.UUCP (Steve Crooks) (03/10/89)
In article <756@twwells.uucp> bill@twwells.uucp (T. William Wells) writes: In article <3998@ttidca.TTI.COM> hollombe@ttidcb.tti.com (The Polymath) writes: : This is the reason I delimit all comments line by line and have fought : to get that practice included in several coding standards. : : C example: : : /* This comment is */ : /* delimited line */ : /* by line. */ : : /* : This is the way : too many other : people do it. : */ : : The above example is a trivial oversimplification that doesn't show how : the second form can cause problems. I've seen several pages of comments, : including some that looked remarkably like source code, delimited with a : single set of /* */. /* * What do you think * about commenting * things using this * style? */ -- --Steve Crooks ...uunet!ingr!b11!crooks!crooks (UUCP) b11!crooks!crooks@ingr.com (Internet) . . . . . . . . . . . . -- --Steve Crooks ...uunet!ingr!b11!crooks!crooks (UUCP) b11!crooks!crooks@ingr.com (Internet)
pattis@june.cs.washington.edu (Richard Pattis) (03/11/89)
X:= 0; (* Initialize both Y:= 0; X and Y to 0. *)
hollombe@ttidca.TTI.COM (The Polymath) (03/16/89)
In article <7563@june.cs.washington.edu> pattis@june.cs.washington.edu (Richard Pattis) writes: }X:= 0; (* Initialize both }Y:= 0; X and Y to 0. *) A classic example. If the above had been written: X:= 0; (* Initialize both *) Y:= 0; (* X and Y to 0. *) The problem would never have arisen. I stand by my recommendation. -- The Polymath (aka: Jerry Hollombe, hollombe@ttidca.tti.com) Illegitimati Nil Citicorp(+)TTI Carborundum 3100 Ocean Park Blvd. (213) 452-9191, x2483 Santa Monica, CA 90405 {csun|philabs|psivax}!ttidca!hollombe