[comp.lang.ada] problems/risks due to programming language, stories requested

gb@cs.purdue.EDU (Gerald Baumgartner) (02/21/90)

For a research project I am collecting information about the risk of
choosing the wrong programming language. In particular I am looking
for problems that could have been avoided if another (a better)
programming language would have been used.

I know of these three such stories:

     1.	There is the famous story that a Mariner probe got lost
	because of the Fortran statement `DO 3 I = 1.3' (1.3 instead
	of 1,3) (see Peter Neumann: A Few Old War Stories Reappear.
	ACM SIGSOFT 11(5), Oct. 1986, pp. 16-18). It is a nice story
	but, as far as I know, NASA used Jovial at that time and not
	Fortran.

     2. One of the security holes the Internet Worm took advantage of
	was in fingerd (the finger deamon). The deamon uses the gets
	routine for input. This routine, written in C, reads input
	without checking for bounds on the buffer involved. By
	overrunning the buffer, the worm rewrote the stack frame (see
	Eugene H. Spafford: Crisis and Aftermath. Communications of
	the ACM 32(6), June 1989).

	There would be no security hole in the finger daemon if a
	programming language would have been used for the I/O
	routines, where the compiler takes care of boundary checks for
	arrays. Pascal doesn't work since variable length strings are
	needed, but Ada would be fine. A language a la ML, where these
	checks are done at compile time, would be even better.

     3. The AT&T breakdown a month ago was caused by a break statement
	in C. See the following mail (multiple forwarding headers deleted):

Subject: AT&T software problem
Subject: Cautionary note on C programming...AT&T learns from experience
>From: kent@wsl.dec.com
Subj:	I've always thought C looked like line noise.
Subj:	the bug
Subj:	AT&T's bug, for you C users out there...
Subj:	I C what they mean!
Subj:	"c" considered dangerous to telephones
Subj:	Be careful from where you break! (else no long distance calls will make it thru...)
Subj:	C switch breaks AT&T switches!
Subj:	your "c users" list might appreciate this....


I received the following on AT&T's famous bug (and have deleted multiple 
forwarding headers):

| | Subject: AT&T Bug
| | Date: Fri Jan 19 12:18:33 1990
| | 
| | This is the bug that cause the AT&T breakdown
| | the other day (no, it wasn't an MCI virus):
| | 
| | In the switching software (written in C), there was a long
| | "do . . . while" construct, which contained
| |    a "switch" statement, which contained 
| |       an "if" clause, which contained a
| |          "break," which was intended for
| |       the "if" clause, but instead broke from
| |    the "switch" statement.
| | 

	Again it looks like this bug wouldn't have occurred in another
	programming language.

You C what I mean? Do you know other stories like these, if possible
with references? I don't want to praise Ada or pick at C and Fortran;
I am looking for any story where a proveably inappropriate/insecure
programming language has been used.


Gerald Baumgartner   gb@cs.purdue.edu   ...!{decwrl,gatech,ucbvax}!purdue!gb

hammondr@sunroof.crd.ge.com (Richard A Hammond) (02/22/90)

In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald Baumgartner) writes:

>For a research project I am collecting information about the risk of
>choosing the wrong programming language. In particular I am looking
>for problems that could have been avoided if another (a better)
>programming language would have been used.

>I know of these three such stories:
	...
>     3. The AT&T breakdown a month ago was caused by a break statement
>	in C. See the following mail (multiple forwarding headers deleted):

>| | This is the bug that cause the AT&T breakdown
>| | the other day (no, it wasn't an MCI virus):
>| | 
>| | In the switching software (written in C), there was a long
>| | "do . . . while" construct, which contained
>| |    a "switch" statement, which contained 
>| |       an "if" clause, which contained a
>| |          "break," which was intended for
>| |       the "if" clause, but instead broke from
>| |    the "switch" statement.
>| | 
>
>	Again it looks like this bug wouldn't have occurred in another
>	programming language.

What other programming language?  Only one without any GOTO or restricted
GOTO (e.g. exit, break, ...).  This leaves out Ada!!!!!!

Similar bug in Ada: 	(Cut down for posting, but gives the flavor)

procedure test is
        MAX : constant := 10; 
        type t is array(positive range 1 .. MAX) of boolean; 
        NEW_ITEMS : t; 
 
    begin 
        for N in 1 .. MAX loop 
	    case ...
	    when ... =>
                if NEW_ITEMS(N) = FALSE then 
			-- some other useful work gets done here
                        exit; 			-- exits loop, not if!
                end if; 
	    when ... =>
	    end case;
        end loop; 
    end test;

So, in the AT&T case using Ada we would have exited both the switch and the
loop rather than just the switch.  Hardly an improvement!

More generally, I find it distressing that the advocates of Ada are
failing to distinguish between language independent features and language
dependent features in assigning credit for software improvements.

In my limited experience the cases where Ada is introduced into a
programming environment also introduce lots of other good software
engineering practices.  For example, lots of people I know who
program in C don't use LINT.   I view it as a deficiency of management
and not of the language that they don't use available tools.

I bring this up because Ada isn't the last language ever to be designed
and we should be willing to learn what could be used in future languages.

Rich Hammond

kassover@jupiter.crd.ge.com (David Kassover) (02/22/90)

In article <5432@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
>In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald Baumgartner) writes:
>
>>For a research project I am collecting information about the risk of
>>choosing the wrong programming language. In particular I am looking
>>for problems that could have been avoided if another (a better)
>>programming language would have been used.
>
>>I know of these three such stories:
>	...
>>     3. The AT&T breakdown a month ago was caused by a break statement
>>	in C. See the following mail (multiple forwarding headers deleted):
>
>What other programming language?  Only one without any GOTO or restricted
>GOTO (e.g. exit, break, ...).  This leaves out Ada!!!!!!
>
>Similar bug in Ada: 	(Cut down for posting, but gives the flavor)
>
>In my limited experience the cases where Ada is introduced into a
>programming environment also introduce lots of other good software
>engineering practices.  For example, lots of people I know who
>program in C don't use LINT.   I view it as a deficiency of management
>and not of the language that they don't use available tools.
 
OK.  First, I apologise for mis-representing the "classic"
FORTRAN goof  (There's one that's actually ambiguous to the
compiler, involving FORMAT statements and Hollerith constants,
but I can never remember it)

Now, AT&T breakdown:
 
You show how this could happen in Ada.  Ok, it could.  But ada
allows one to "name" loops, and use those names in exit
statements, especially useful when you want to break out of an
inner and an outer loop.  In your example, you didn't do so,
since the C code could not.  But you could have.
 
Looking back at the last 20Klines of Ada I've written recently,
I've used named loops roughly twice.  Specifically to avoid
ambiguity to me when I look at the code, but it helps make sure
I did it right, too.
 
You go on to bemoan the lack of use of LINT.  I submit that,
since we're not dependent on underpowered pdp9's or 11's anymore,
then LINT should be built into the compiler, or there as the
default option  (to be turned off at the user's risk)

And onward, to problems that are exacerbated by the language.  

Time and again, my C development people spend oodles of effort
tracking down something that ends up being resolved by
discovering a header file that was changed, but not *all* of the
dependent code was recompilied.  Use make, you say?  Sure, but
someone's got to write the make script, whose language is no gem,
either.
 
Ada's insistence on specification recompile (and lack of a
include processor) cause the dependency tree to be built and
modified automatically.  (in Vax ada, you can enter "foreign
language" object modules into the library, so they, too, can
participate in obsolescence analysis.  I don't know if anyone
else provides this, or how well it works)
 
 
On a par in terms of frequency with the above is the case of the
non-catchalled case statement.  In ada, if you have a case
statement of an enumerated type, and you do not provide a case
for every member of the type or a when others => clause, the
compiler signals an error.  No, this doesn't stop someone putting
a when others => null; in, but most of us either use the compiler
to remind us to put in an appropriate case or cause a fatal error
to occur in the catchall, the theory being that it will blow up
in testing, and the appropriate case added.
 
Finding this thing in C is a bear, especially when, if your code
is like mine, three quarters of it is conditional compile based
on flags set in a header file somewhere.
 
And just as a final note:  I have demonstrated many times that it
is possible to write FORTRAN in Ada.  About the only places I
haven't been able to do so, if I really wanted to, have been APL
and assembler.  That doesn't mean that either Ada or FORTRAN are
valueless. 

hammondr@sunroof.crd.ge.com (Richard A Hammond) (02/22/90)

In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald Baumgartner) writes:

>For a research project I am collecting information about the risk of
>choosing the wrong programming language. In particular I am looking
>for problems that could have been avoided if another (a better)
>programming language would have been used.

RE: AT&T example
OK folks, I was not trying to say that C was as good as Ada,
I merely pointed out that in both C and Ada one could have a
legal program that had a restricted goto (C "break", Ada "exit")
inside an if, and that neither language's compilers could detect
whether the programmer really wanted that or not.  This, to my
mind, makes the example not fit the class that was requested,
of cases where a different language would have prevented the
problem.


In article <5458@crdgw1.crd.ge.com> kassover@jupiter.crd.ge.com (David Kassover) writes:
...
>Time and again, my C development people spend oodles of effort
>tracking down something that ends up being resolved by
>discovering a header file that was changed, but not *all* of the
>dependent code was recompilied.  Use make, you say?  Sure, but
>someone's got to write the make script, whose language is no gem,
>either.

The oodles of time is an exageration, since, painful though it
might be, writing the make script would solve the problem once
and for all.  This suggests that the cost to find the numerous
problems is less than to write a make script.  By the way, there are
tools available to automatically generate most of the makefile.
Besides, if you have a make script you can cause lint to run
automatically, which is a nice side benefit.

>Ada's insistence on specification recompile (and lack of a
>include processor) cause the dependency tree to be built and
>modified automatically.  (in Vax ada, you can enter "foreign
>language" object modules into the library, so they, too, can
>participate in obsolescence analysis.  I don't know if anyone
>else provides this, or how well it works)
 
And it is a real pain when the compiler has a bug in the implementation,
as does the Ada compiler we're using.  If you change a generic body
it messes up its internal information and you end up recompiling
everything, so we end up avoiding the built-in "make" of Ada and
writing make scripts to get the proper recompilations done.
Maintaining the make scripts costs less time than recompiling
everything every time you change a generic body.
Building everything into the compiler does have disadvantages.

>On a par in terms of frequency with the above is the case of the
>non-catchalled case statement. ...
 
>Finding this thing in C is a bear, especially when, if your code
>is like mine, three quarters of it is conditional compile based
>on flags set in a header file somewhere.

So, in Ada you either write incomplete code (because the compiler
will catch it) or you raise an exception(I imagine) in the "others"
case.  I don't see why you can't  adopt the second solution in C.
If it happens often, adopt a coding style to minimize it, always
put "default: abort();" in your switch statements.

Your complaints remind me of the old chinese saying (Rich's paraphrase)
Fooled once, shame on the language which fooled you.
Fooled twice, shame on you.

Rich Hammond

kassover@control.crd.ge.com (David Kassover) (02/23/90)

In article <5464@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
>In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald Baumgartner) writes:
>
>>For a research project I am collecting information about the risk of
>>choosing the wrong programming language.
>In article <5458@crdgw1.crd.ge.com> kassover@jupiter.crd.ge.com (David Kassover) writes:
>...
>>Time and again, my C development people spend oodles of effort
>>tracking down something that ends up being resolved by
>>discovering a header file that was changed, but not *all* of the
>>dependent code was recompilied.  Use make, you say?  Sure, but
>>someone's got to write the make script, whose language is no gem,
>>either.
>
>The oodles of time is an exageration, since, painful though it
>might be, writing the make script would solve the problem once
>and for all.
>
"Oodles" is a rather imprecise term.  I apologize.  But you
aren't here.  Almost time I visit my development people, they are
chasing some sort of bug that was traced to this case, or a
missing catchall.  I may have sampling error problems, I admit it.
>>Ada's insistence on specification recompile (and lack of a
>>include processor) cause the dependency tree to be built and
>>modified automatically.  (in Vax ada, you can enter "foreign
>>language" object modules into the library, so they, too, can
>>participate in obsolescence analysis.  I don't know if anyone
>>else provides this, or how well it works)
> 
>And it is a real pain when the compiler has a bug in the implementation,
>as does the Ada compiler we're using.
>...
If your compiler has a bug (Since Ada is thoroughly standardized,
one standard, no extensions, no subsets) then you should get it
fixed or get a different compiler.

>Maintaining the make scripts costs less time than recompiling
>everything every time you change a generic body.
>Building everything into the compiler does have disadvantages.
>...
Well, you're there, and I'm not.  But attempting to do a
professional job with amateur's tools, or amateur quality tools,
is likely to be frustrating, among other things.  This is not a
problem with the language, it's a problem with the implementation
your stuck with.


By the way, the product line I am dealing with is supported on
more than 20 different operating systems, only some of which are
Unix, or Unix-like, some of which do not offer a make-analog, and
even of the ones which do, the make scripts have to be (only
sometimes subtly) different.  I simply do not have time, nor the
charter, to implement make for everybody
>
>>On a par in terms of frequency with the above is the case of the
>>non-catchalled case statement. ...
> 
>>Finding this thing in C is a bear, especially when, if your code
>>is like mine, three quarters of it is conditional compile based
>>on flags set in a header file somewhere.
>
>So, in Ada you either write incomplete code (because the compiler
>will catch it) or you raise an exception(I imagine) in the "others"
>case.
>...
No, I didn't write incomplete code and wait for the compiler to
catch it.  (I've used this technique elsewhere, though).  It is
common, in the ada I have seen, to define in a package
specification an enumerated type.  Later on, someone adds an
element to the type.  (e.g. support for a different type of data
structure, or even, as is the case, add a new package to the
system.  (this system keeps track of the names of it's packages,
in order to generate traceback information during runtime user
errors))

The code in the package body contains a case statement on the
enumerated type.  It was not created incomplete, but it was
RENDERED incomplete by the insertion of a new element.  Since
recompilation is of this body is forced, without having to
remember to modify the make script (we've already forgotten to
modify the package body, remember), this error is fixed before
the module gets out of unit test.

this is not to say that the compilable code in the case statement
is not erroneous, but falling off the end of the case statement
is probably at least as bad.  That is, some human has to exert
effort to allow the case statement to be fallen through, rather
than it being allowed to happen.
>
>If it happens often, adopt a coding style to minimize it, always
>put "default: abort();" in your switch statements.
>
>...
This is the real world.  I have little time to fight with my
people over personal style, and I don't want to be viewed as a
tin pot tyrant over stylistic issues.  My concerns are getting
the product out there, with as few errors as possible.  Ada
appears to help in this regard more than C does.  I'm sure you
and your employers have a somewhat different agenda.
 

Dave Kassover

kassover@control.crd.ge.com (David Kassover) (02/23/90)

by the way, are we discussing Ada here, or structured
programming?
 
I've already made up my mind (LONG AGO) about one of them... :-)

Dave

tom@hprmokg.HP.COM (Thomas Vachuska) (02/24/90)

    Maybe I am missing the point here, but to the best of my knowledge
Ada "exit" statement is allowed only within a "named loop|loop" statement
(unless it appears in a "subprogram|package|generic|task|accept body" which is 
enclosed within that "loop" statement, to be precise).  And as far as I know
similar restrictions apply for the use of the C "break" statement which 
terminates the execution of either the "while|do|for" or "switch" statement.  
Neither of these are to abandon execution of an "if" statement block.
    I would agree that it is easier to get in trouble in the following 
situation in C which does not have a counterpart in Ada since Ada's "exit"
exits ONLY the "loop" statement.

    switch (trouble) {
        case PROGRAMMER_SCREW_UP: 
            for (;;) {
                break;    /* intended for exiting the "switch", BUT... */
            }
        case ...
        .
        .
    }


Thomas Vachuska  (-- Ada Addict)

msb@sq.sq.com (Mark Brader) (02/24/90)

Gerald Baumgartner (gb@cs.purdue.EDU) writes in many groups:
> There is the famous story that a Mariner probe got lost
> because of the Fortran statement `DO 3 I = 1.3' (1.3 instead
> of 1,3) ... It is a nice story but, as far as I know, NASA used
> Jovial at that time and not Fortran.

Just for the record, the above was definitively shown to be fictional
according to authoritative references given in comp.risks (= Risks Digest),
issue 9.75 (I hear), not too many months ago.  There is at least one
textbook that states it as truth; this is wrong.  The actual reason for
the loss of Mariner I was an error in code used in recovering from a
hardware failure; the code had been based on handwritten equations, and
in transcribing one of these, an overbar was deleted from one letter.

A story which may have been the true origin of the "DO statement myth"
was posted fairly recently in alt.folklore.computers; the article
cited a program at NASA that did enter production use with a dot-for-comma
bug in a DO statement, but it wasn't a spacecraft flight control program.
(I didn't save the details and would be happy to see them again.)

Followups directed to alt.folklore.computers.

-- 
Mark Brader			"I'm not going to post a revision: even USENET
utzoo!sq!msb, msb@sq.com	 readers can divide by 100."	-- Brian Reid

This article is in the public domain.

bill@ssd.harris.com (Bill Leonard) (02/28/90)

In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald Baumgartner) writes:

   I received the following on AT&T's famous bug (and have deleted multiple 
   forwarding headers):

   | | Subject: AT&T Bug
   | | Date: Fri Jan 19 12:18:33 1990
   | | 
   | | This is the bug that cause the AT&T breakdown
   | | the other day (no, it wasn't an MCI virus):
   | | 
   | | In the switching software (written in C), there was a long
   | | "do . . . while" construct, which contained
   | |    a "switch" statement, which contained 
   | |       an "if" clause, which contained a
   | |          "break," which was intended for
   | |       the "if" clause, but instead broke from
   | |    the "switch" statement.
   | | 

           Again it looks like this bug wouldn't have occurred in another
           programming language.

I can't resist saying that this last statement seems to me to be utter
nonsense.  What programming language (read, compiler) can read the
programmer's mind and tell what he meant?  The use of the "break" statement
was a logic error (actually, it sounds like it was a lack of knowledge of
the language, since "break" does not apply to "if").  I can't imagine a
programming language that could discern this type of error.  [If I use
WHILE instead of IF, for instance, I can expect some things to work and
some not.  Yet I seriously doubt any compiler could possibly detect this
error.]

I certainly think programmers often choose an inappropriate language, but I
shy away from anecdotal stories like these because they seem (to me) to
spread a lot of misinformation.  Unless you implement a project in multiple
languages, it is nothing more than a guess to say what would have happened
if the project had been implemented in some other language.  Perhaps you
would have discovered an even more serious flaw in that language, or you
might simply find it was no better or worse than the one you chose, just
different.

Most of the stories I have heard along these lines all struck me as missing
the point: how well was the program tested?  Were there code reviews?
Design reviews?  All of these techniques are proven to reduce errors.  Most
of the errors in these stories (e.g., the infamous dot-versus-comma one)
should have been found with even rudimentary testing.

Use of an inappropriate language is no excuse for abandoning other techniques
of good software engineering.
--
Bill Leonard
Harris Computer Systems Division
2101 W. Cypress Creek Road
Fort Lauderdale, FL  33309
bill@ssd.csd.harris.com or hcx1!bill@uunet.uu.net

chewy@apple.com (Paul Snively) (03/01/90)

In article <BILL.90Feb27143004@hcx2.ssd.harris.com> bill@ssd.harris.com 
(Bill Leonard) writes:
> In article <9790@medusa.cs.purdue.edu> gb@cs.purdue.EDU (Gerald 
Baumgartner) writes:
>            Again it looks like this bug wouldn't have occurred in another
>            programming language.
> 
> I can't resist saying that this last statement seems to me to be utter
> nonsense.  What programming language (read, compiler) can read the
> programmer's mind and tell what he meant?  The use of the "break" 
statement
> was a logic error (actually, it sounds like it was a lack of knowledge of
> the language, since "break" does not apply to "if").  I can't imagine a
> programming language that could discern this type of error.  [If I use
> WHILE instead of IF, for instance, I can expect some things to work and
> some not.  Yet I seriously doubt any compiler could possibly detect this
> error.]
> 
> I certainly think programmers often choose an inappropriate language, 
but I
> shy away from anecdotal stories like these because they seem (to me) to
> spread a lot of misinformation.  Unless you implement a project in 
multiple
> languages, it is nothing more than a guess to say what would have 
happened
> if the project had been implemented in some other language.  Perhaps you
> would have discovered an even more serious flaw in that language, or you
> might simply find it was no better or worse than the one you chose, just
> different.
> 
> Most of the stories I have heard along these lines all struck me as 
missing
> the point: how well was the program tested?  Were there code reviews?
> Design reviews?  All of these techniques are proven to reduce errors.  
Most
> of the errors in these stories (e.g., the infamous dot-versus-comma one)
> should have been found with even rudimentary testing.
> 
> Use of an inappropriate language is no excuse for abandoning other 
techniques
> of good software engineering.

I don't think that anyone's claiming that it is an excuse; I believe the 
point was that some languages applied to some tasks lend themselves to 
error more than another language applied to the same task.  If you wish to 
interpret the above story as a rather pointed jab at the C programming 
language, and object to C being treated that way, that's fine, but please 
just say so.

For what it's worth, my personal opinion is that C lends itself to 
precisely the kinds of errors noted above--when does break work and when 
doesn't it, and why in God's name do you need it in switch statements in 
the first place, etc.  I believe that it's C's historical looseness that 
is simultaneously its greatest weakness, when it leads to errors like 
this, and its greatest strength--C doesn't restrict you; C is mean and 
lean; C is close to the hardware; real programmers use C; even, God help 
us, C is the only language you need!  We all know C programmers whose 
machismo is thus huffed and puffed up (another of my personal opinions is 
that the per capita arrogance of C programmers far outweighs the per 
capita arrogance of any other language-aficionado group).

Now to get back to the important point: what language would have been 
better for the task in question?

Well, I hate to say it, but it's extremely unlikely that such an error 
would have been made in Pascal, since Pascal doesn't require you to 
explicitly break from case...of constructs.

Before the flames start, let me just add: no, I don't necessarily prefer Pascal over C for all tasks.  I generally attempt to choose the right tool for the job, rather than falling into the "when all you have is a hammer, everything looks like a nail" trap.

Standard Disclaimer.

jk0@image.soe.clarkson.edu (Jason Coughlin) (03/01/90)

From article <6960@internal.Apple.COM>, by chewy@apple.com (Paul Snively):
> For what it's worth, my personal opinion is that C lends itself to 
> precisely the kinds of errors noted above--when does break work and when 
> doesn't it, and why in God's name do you need it in switch statements in 
> the first place, etc.

	Gee, if you read the language defn you'd know exactly when break
applies and when break doesn't.  It seems to me that it is the
programmer's responsibility to know the language in which he is going to
implement said project -- it's not necessarily the language's responsibility
to know the programmer didn't read the defn.

> Well, I hate to say it, but it's extremely unlikely that such an error 
> would have been made in Pascal, since Pascal doesn't require you to 
> explicitly break from case...of constructs.

	And without knowing the project, you have no business making the
assertion that Pascal was better than C [especially on a Unix box] or
that C was better than Pascal [especially on a VMS box].
-- 
Jason Coughlin ( jk0@sun.soe.clarkson.edu , jk0@clutx )
"Every jumbled pile of person has a thinking part that wonders what the
part that isn't thinking isn't thinking of." - They Might Be Giants

jeff@aiai.ed.ac.uk (Jeff Dalton) (03/01/90)

In article <6960@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
 >machismo is thus huffed and puffed up (another of my personal opinions is 
 >that the per capita arrogance of C programmers far outweighs the per 
 >capita arrogance of any other language-aficionado group).

Except for Pascal programmers.  Even Wirth has moved on by now.

barmar@think.com (Barry Margolin) (03/02/90)

In article <1990Feb28.213543.21748@sun.soe.clarkson.edu> jk0@image.soe.clarkson.edu (Jason Coughlin) writes:
>	Gee, if you read the language defn you'd know exactly when break
>applies and when break doesn't.  It seems to me that it is the
>programmer's responsibility to know the language in which he is going to
>implement said project -- it's not necessarily the language's responsibility
>to know the programmer didn't read the defn.

What would you say if a car designer used a similar excuse: Gee, if you'd
read the owner's manual for the 6000SUX you'd know that you have to turn
the radio off before stepping on the brake pedal.  It seems to me that it
is the driver's responsibility to know the car he's driving -- it's not
necessarily the manufacturer's responsibility to know that the driver
didn't read the manual.

Yes, it's the resposibility of the programmer to know the language.  But
it's the responsibility of language designers to design languages
reasonably.  If programmer-friendliness weren't an issue we'd still be
programming in machine language.
--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

lins@Apple.COM (Chuck Lins) (03/02/90)

In article <1883@skye.ed.ac.uk> jeff@aiai.UUCP (Jeff Dalton) writes:
>In article <6960@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
> >machismo is thus huffed and puffed up (another of my personal opinions is 
> >that the per capita arrogance of C programmers far outweighs the per 
> >capita arrogance of any other language-aficionado group).
>
>Except for Pascal programmers.  Even Wirth has moved on by now.

                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Yup. Even beyond Modula-2 to Oberon. And several colleagues at ETHZ have
enhance Oberon with object-oriented extensions.

-- 
Chuck Lins               | "Exit left to funway."
Apple Computer, Inc.     | Internet: lins@apple.com
20525 Mariani Avenue     | AppleLink: LINS
Mail Stop 41-K           | 
Cupertino, CA 95014      | "Self-proclaimed Object Oberon Evangelist"
The intersection of Apple's ideas and my ideas yields the empty set.

hammondr@sunroof.crd.ge.com (Richard A Hammond) (03/02/90)

Slowly, and carefully, for Bill Wolfe's understanding, let's go through this
once more.

The original article asked for examples of cases where using a different
language would have prevented the error.  He gave 3 examples, one of
which was:
   | | Subject: AT&T Bug
   | | Date: Fri Jan 19 12:18:33 1990
   | | 
   | | This is the bug that cause the AT&T breakdown
   | | the other day (no, it wasn't an MCI virus):
   | | 
   | | In the switching software (written in C), there was a long
   | | "do . . . while" construct, which contained
   | |    a "switch" statement, which contained 
   | |       an "if" clause, which contained a
   | |          "break," which was intended for
   | |       the "if" clause, but instead broke from
   | |    the "switch" statement.

I claim that this information is insufficient to find C guilty in this case.
This is not to say that you can't find examples in C of such problems.
To name a few:

1) Comments with Begin/End delimiters can easily hide code if one leaves
   out the end comment delimiter.  Particularly bad if the compiler doesn't
   warn about nested comments.  This also applies to Pascal, CMS-2, JOVIAL, ...

2) Writing :	if ( a = b )
   rather than:	if ( a == b )

3) Leaving out the "break" at the end of a case.

All these are directly caused by C's language design and another language
would avoid one or more of them (Ada avoids them all).

If the explanation for the AT&T bug was:

we originally had:		we changed it to:
	case ...:		case ...: if (...) {
		stmts_a				stmts_a;
		break;				break;	 -- should have removed
					   }
					   stmts_b;

Then I would agree that it is possible to follow Bill's argument and
assign the bug to the language, although even there it is a bit of a stretch.

But, the explanation is "... a "break," which was intended for the "if" clause."
Which doesn't support any conclusion other than the programmer didn't know
the language.

Why re-hash this?  Well, I'm tired of Bill Wolfe's arguments which run:

We know that Communism is evil.  We know that they had a bad reactor accident.
Therefore, changing to capitalism would have prevented the reactor accident!

I suggest that Bill needs some more elementary logic courses if he really thinks
that the statement of the AT&T bug supports his conclusion.

It would be very helpful if the original poster (from Purdue) explained why
he thought that the bug statement supported assigning it to the class of bugs
prevented by using a different language.

I agree with Bill that C does not provide very good support for the software
engineering process.  I think the examples I gave above are clear examples,
the AT&T bug statement is not.

Rich Hammond

dave@micropen (David F. Carlson) (03/03/90)

In article <6960@internal.Apple.COM>, chewy@apple.com (Paul Snively) writes:
> 
> 
> For what it's worth, my personal opinion is that C lends itself to 
> precisely the kinds of errors noted above--when does break work and when 
> doesn't it, and why in God's name do you need it in switch statements in 
> the first place, etc.

What break does is *very* well defined and is no more prone to misinterpretation
that any other non-linear control flow statement in any other PL.

From K&R2 p 244:

	A9.5: iteration statement is (for, while, do)...

	A break statement may appear only in an iteration statement or a switch 
	statement; control passes to the statement following the terminated
	statement.

A multi-case switch is very handy in many situations to reduce identical
treatments for similar cases.  That you ask the question of the usefulness
of break-per-case/multiple-cases implies that you haven't sufficient experience
with the construct to judge its merits/weaknesses.

Dijkstra notes that no programming language can prevent a poor programmer from
creating bad programs.

-- 
David F. Carlson, Micropen, Inc.
micropen!dave@ee.rochester.edu

"The faster I go, the behinder I get." --Lewis Carroll

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (03/03/90)

From hammondr@sunroof.crd.ge.com (Richard A Hammond):
%    | | In the switching software (written in C), there was a long
%    | | "do . . . while" construct, which contained
%    | |    a "switch" statement, which contained 
%    | |       an "if" clause, which contained a
%    | |          "break," which was intended for
%    | |       the "if" clause, but instead broke from
%    | |    the "switch" statement.
> 
> Which doesn't support any conclusion other than the programmer didn't know
> the language.

   Not exactly.  There is a lack of orthogonality in that similar
   flow-of-control constructs do not terminate in similar ways.  If
   one is using the if statement, termination is automatic.  If one 
   is using the switch statement, a break is required.  It is this
   lack of orthogonality which leads to potential problems.


   Bill Wolfe, wtwolfe@hubcap.clemson.edu
 

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (03/03/90)

From dave@micropen (David F. Carlson):
>> For what it's worth, my personal opinion is that C lends itself to 
>> precisely the kinds of errors noted above--when does break work and when 
>> doesn't it, and why in God's name do you need it in switch statements in 
>> the first place, etc.
> 
> A multi-case switch is very handy in many situations to reduce identical
> treatments for similar cases.  

   So is a multi-alternative case, as provided by Ada:

      case Foo is
         when 1 | 3 | 5 =>
            statement1;
         when 2 | 4 | 6 =>
            statement2;
         when others =>
            statement3;
      end case;

   The difference is that Ada takes care of exiting the case statement
   for you, whereas C requires (unsafely) that you use a break to avoid 
   being sucked into the code associated with subsequent cases.  


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

hammondr@sunroof.crd.ge.com (Richard A Hammond) (03/03/90)

In article <8211@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>From hammondr@sunroof.crd.ge.com (Richard A Hammond):
>%    | | In the switching software (written in C), there was a long
>%    | | "do . . . while" construct, which contained
>%    | |    a "switch" statement, which contained 
>%    | |       an "if" clause, which contained a
>%    | |          "break," which was intended for
>%    | |       the "if" clause, but instead broke from
>%    | |    the "switch" statement.
 
>> Which doesn't support any conclusion other than the programmer didn't know
>> the language.

>   Not exactly.  There is a lack of orthogonality in that similar
>   flow-of-control constructs do not terminate in similar ways.  If
>   one is using the if statement, termination is automatic.  If one 
>   is using the switch statement, a break is required.  It is this
>   lack of orthogonality which leads to potential problems.
				         ^^^^^^^^^ 
weasel words!!  Potential cause /= actual cause.
Reduced probability /= 0.0 probability

Daggone it Bill, why don't you try to understand?

You're quoting this out of context, the whole point of my posting was
that the statement of the bug does not provide sufficient information
to say that changing the language would have PREVENTED the problem.

I gave 3 other examples (of C code problems) where the bug was one that
would have been PREVENTED by use of Ada.

Rich Hammond

bouma@cs.purdue.EDU (William J. Bouma) (03/03/90)

In article <6960@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>We all know C programmers whose 
>machismo is thus huffed and puffed up (another of my personal opinions is 
>that the per capita arrogance of C programmers far outweighs the per 
>capita arrogance of any other language-aficionado group).


   Oh, really! I can tell you have never met any FORTH programmers.

 
>Well, I hate to say it, but it's extremely unlikely that such an error 
>would have been made in Pascal, since Pascal doesn't require you to 
>explicitly break from case...of constructs.


   Well isn't that special! The way I see it, C gives you the flexibility
   to not break if you don't want to, where PASCAL restricts you to break.


>Before the flames start,

   Too late!

> let me just add: no, I don't necessarily prefer Pascal over C for all tasks.


   The only place I can see to prefer PASCAL over C is a beginner programming
   class. Isn't PASCAL usually thrown out along with the diapers?
   
-- 
Bill <bouma@cs.purdue.edu>  |  And don't forget my dog... "Astronomy" -- BOC

jlg@lambda.UUCP (Jim Giles) (03/03/90)

From article <1004@micropen>, by dave@micropen (David F. Carlson):
> [... explicit breaks in the C switch construct ...]
> Dijkstra notes that no programming language can prevent a poor programmer from
> creating bad programs.

He also notes that the choice of programming language can have a strong
effect on the quality of the resulting code.  (His indictment of PL/I
as being similar to flying a widebodied jet with all the windows taped
over and no labels on the thousands of controls was quite apropos.)
This effect of the language choice is mainly psychological - and it
CAN be overcome (which is the main thrust of many of Dijkstra's works).
But, be honest, how many programmers do you know who _really_ construct
their programs abstractly _before_ even selecting their implementation
language?  This is the proper way (a' la Dijkstra) to make sure the
you aren't negatively impacted by the language - you select the proper
language for the job at hand - you don't mangle the job to fit the
language.

Dijkstra's statement, while true, should not be used to excuse poorly
designed language features (as you are trying to do).  A better design
for C would have been _not_ to require breaks after each case and to
provide some other syntax for the representation of multiple choices
on the same case.  It's easy to see these kinds of design errors
in retrospect (C _is_ nearly 20 years old you know).

J. Giles

manis@cs.ubc.ca (Vincent Manis) (03/03/90)

I might note that B's syntax, and hence C's syntax, was a definite
*dis*improvement [sic] over that of its predecessor, BCPL. I would in
fact post an article saying exactly that, except for the fact that this
entire thread most certainly belongs somewhere, but not in
comp.lang.scheme.  Would you please edit the Newsgroups: line in further
articles on this subject?

--
\    Vincent Manis <manis@cs.ubc.ca>      "There is no law that vulgarity and
 \   Department of Computer Science      literary excellence cannot coexist."
 /\  University of British Columbia                        -- A. Trevor Hodge
/  \ Vancouver, BC, Canada V6T 1W5 (604) 228-2394

eaker@sunbelt.crd.ge.com (Charles E Eaker) (03/04/90)

In article <8211@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>From hammondr@sunroof.crd.ge.com (Richard A Hammond):
>%    | | In the switching software (written in C), there was a long
>%    | | "do . . . while" construct, which contained
>%    | |    a "switch" statement, which contained 
>%    | |       an "if" clause, which contained a
>%    | |          "break," which was intended for
>%    | |       the "if" clause, but instead broke from
>%    | |    the "switch" statement.
>> 
>> Which doesn't support any conclusion other than the programmer didn't know
>> the language.
>
>   Not exactly.  There is a lack of orthogonality in that similar
>   flow-of-control constructs do not terminate in similar ways.  If
>   one is using the if statement, termination is automatic.  If one 
>   is using the switch statement, a break is required.  It is this
>   lack of orthogonality which leads to potential problems.

Ok, so the implied orthogonality of Ada means that, without putting
a whole lot of thought into it, I can map the above C outline to
Ada as follows:

  In the switching software (TRANSLATED to Ada), there was a long
   "LOOP" construct, which contained
      a "CASE" statement, which contained 
         an "IF" clause, which contained an
            "EXIT," which was intended for
         the "IF" clause, but instead broke from
      the "LOOP" statement.

and if there's a mistake here, it's because of the lack of orthogonality
of Ada (which we all know is laughable) rather than any misunderstanding
of the language on my part. Right?  Hmm, maybe I'll stop working in Ada
and go back to C. I like the idea of the language taking the wrap for
what some misguided souls have viewed as my mistakes.  But wait! Maybe
I can stick with Ada. All I have to do is show, somehow, that Ada is
not all that orthogonal ... hmm ...

--
Chuck Eaker                                |  eaker@sunbelt.crd.ge.com
Software Engineering Program               |  eaker@crdgw1.UUCP
GE Corporate Research & Development Center |  (518) 387-5964
P.O. Box 8, K-1 3C12 Schenectady, NY 12301 |  8*833-5964

jbaker@gmu90x.gmu.edu (jbaker) (03/06/90)

In article <8218@hubcap.clemson.edu> Bill Wolf writes:
>From dave@micropen (David F. Carlson):
>>> For what it's worth, my personal opinion is that C lends itself to 
>>> precisely the kinds of errors noted above--when does break work and when 
>>> doesn't it, and why in God's name do you need it in switch statements in 
>>> the first place, etc.
>> 
>> A multi-case switch is very handy in many situations to reduce identical
>> treatments for similar cases.  

But the real usefulness of requiring break in a switch statement is for
SIMILAR treatments of similar cases, for example you may require a
few assignments in one case before a more complicated computation which
must be performed for several of the cases.

This could be done in other languages using conditionals or multiple case
statements, but it's not quite as nice.

Bill Wolf writes:
>   So is a multi-alternative case, as provided by Ada:
>
>      case Foo is
>         when 1 | 3 | 5 =>
>            statement1;
>         when 2 | 4 | 6 =>
>            statement2;
>         when others =>
>            statement3;
>      end case;
>
>   The difference is that Ada takes care of exiting the case statement
>   for you, whereas C requires (unsafely) that you use a break to avoid 
>   being sucked into the code associated with subsequent cases.  
>
But this is just one example of the design philosophy of C: flexibility;
if the machine will let you do it (or naturally WANTS to do it), let the
programmer do it the same way.  Other examples of such flexibilty are the
lack of type-checking, as well as allowing assignments just about anywhere.

Some languages, such as Pascal, have more limitations (or less extentions)
in their constructs.  This usually is perfectly adequate, but for someone
who writes code while thinking about how the machine will execute that 
code, as I do, flexibility can be useful; a small amount of speed-up, and more
compact code can be the result. 

However, this capability has a trade-off; flexibility for follow-ability.
Humans do not think like computers.  We can not precisely process syntax.
When code becomes too involved, it can become very difficult to follow for
even the author.  What could be a straight-foward program may now be a twisted
mess.  It becomes easy to overlook bugs that would be obvious in other
languages.  This is why C programmers rely heavily on a debugger.
What one calls "safety" in a language, then, is just how well humans can
follow a construct, without regard for its usefulness.  C is not "safe,"
but while being quite simple and relatively low-level, it contains many
flexible constucts.

Sometimes, though, flexibility is present in other languages in a more
"safe" fashion.  For example, type conversion is available in Modula-2
IF it is explicitly done in the code.  In order to use a pointer as a
integer, for example, one might use: INTEGER(ch^).  This flags the compiler
that "we meant to do that" and warns humans that something tricky is going on.

But C can be delightful to use, if you are very careful to write clear code.


John Baker
jbaker@gmuvax.gmu.edu

Now about deciphering all those }++|#{ symbols....

boone@IDA.ORG (John Boone) (03/07/90)

In article <8211@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:


>   Not exactly.  There is a lack of orthogonality in that similar
>   flow-of-control constructs do not terminate in similar ways.  If
>   one is using the if statement, termination is automatic.  If one
>   is using the switch statement, a break is required.  It is this
>   lack of orthogonality which leads to potential problems.


	This is a minor flame, but I feel it's necessary since literally 
	millions :-) of CS students worldwide read these news groups and 
	learn from them.  So I think you should be more careful using
	four-syllable words :-)

	Orthogonal means, roughly, "at right angles to" - so I think your
	point is really BECAUSE of orthogonality in the flow-of-control
	constucts [ for C ] which leads to potential problems ... etc.

-- 

   ...........................................................................
   :     J. M. Boone      :                                                  :
   :                      :     Tenacity of purpose for a rightful cause     :

lou@atanasoff.rutgers.edu (Lou Steinberg) (03/08/90)

In article <2596@gmu90x.gmu.edu> jbaker@gmu90x.gmu.edu (jbaker) writes:

> In article <8218@hubcap.clemson.edu> Bill Wolf writes:
> >From dave@micropen (David F. Carlson):
> >> A multi-case switch is very handy in many situations to reduce identical
> >> treatments for similar cases.  
> 
> But the real usefulness of requiring break in a switch statement is for
> SIMILAR treatments of similar cases, for example you may require a
> few assignments in one case before a more complicated computation which
> must be performed for several of the cases.

ARGHHH!!  That is what subroutines (and macros) are for - to handle
common code.  And if your language makes them too expensive, either in
terms of run time or in terms of programmer effort, then THAT is an
even worse problem with the language than the problems with break.
-- 
					Lou Steinberg

uucp:   {pretty much any major site}!rutgers!aramis.rutgers.edu!lou 
arpa:   lou@cs.rutgers.edu

ciardo@software.org (Gianfranco Ciardo) (03/09/90)

In article <Mar.8.10.19.49.1990.3812@atanasoff.rutgers.edu> lou@atanasoff.rutgers.edu (Lou Steinberg) writes:
> > >> A multi-case switch is very handy in many situations to reduce identical
> > >> treatments for similar cases.  
> ARGHHH!!  That is what subroutines (and macros) are for - to handle
> common code.  And if your language makes them too expensive, either in
> terms of run time or in terms of programmer effort, then THAT is an
> even worse problem with the language than the problems with break.

I think you miss completely the point.
Using subroutines is not going to help you make the code shorter, more compact,
or less repetitious (which is not) in a case like this:

          switch (what_to_do) {
                    case FIVE_THINGS:
                            <statementA>;
                    case FOUR_THINGS:
                            <statementB>;
                    case THREE_THINGS:
                            <statementC>;
                    case TWO_THINGS:
                            <statementD>;
                    case ONE_THING:
                            <statementE>;
                    case NOTHING:
                            break;
          }

kassover@jupiter.crd.ge.com (David Kassover) (03/10/90)

In article <672@software.software.org> ciardo@software.org (Gianfranco Ciardo) writes:
...
>
>I think you miss completely the point.
>Using subroutines is not going to help you make the code shorter, more compact,
>or less repetitious (which is not) in a case like this:
>
>          switch (what_to_do) {
>                    case FIVE_THINGS:
>                            <statementA>;
>                    case FOUR_THINGS:
>                            <statementB>;
>                    case THREE_THINGS:
>                            <statementC>;
>                    case TWO_THINGS:
>                            <statementD>;
>                    case ONE_THING:
>                            <statementE>;
>                    case NOTHING:
>                            break;
>          }

No, but without fall through, you would write such a thing upside
down.  Or do something else.
 
A couple of weeks ago I mentioned a (please bear with me) Fortran
preprocessor called FLEX, which provided 4 kinds of case
statement, two with fall through, two without.
 
One instance:  A particular programmer, whom I have worked with
for about 10 years, rarely, if ever, used the FLEX
cases-with-fallthrough.
 
Now that he has learned C (and not recently, bTW), it seems like
he goes out of his way to *USE* fall-through.


I wonder why it is so difficult for language designers to provide
more than one way to do things?

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (03/10/90)

In article <672@software.software.org>, ciardo@software.org (Gianfranco Ciardo) writes:
> Using subroutines is not going to help you make the code shorter, more compact,
> or less repetitious (which is not) in a case like this:
> 
>           switch (what_to_do) {
>                     case FIVE_THINGS:
>                             <statementA>;
>                     case FOUR_THINGS:
>                             <statementB>;
			[etc.]
>                     case ONE_THING:
>                             <statementE>;
>                     case NOTHING:
>                             break;
>           }

No, but writing the code like this will:

	if (what_to_do >= ONE_THING) <statementE>;
	if (what_to_do >= TWO_THINGS) <statementD>;
	if (what_to_do >= THREE_THINGS) <statementC>;
	if (what_to_do >= TWO_THINGS) <statementB>;
	if (what_to_do >= ONE_THING) <statementA>;

If you wish to quibble over my use of inequalities, replace them with
a disjunction of equalities.

Erann Gat                  gat@robotics.jpl.nasa.gov

sanders@sanders.austin.ibm.com (Tony Sanders) (03/10/90)

In article <8218@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>   So is a multi-alternative case, as provided by Ada:
How do you do this in ADA?

    switch(n) {
      case 0:
	count++;
      case 1:
	ocount++;
      case 2:
	printf("%d %d\n",count,ocount);
	break;
      default:
	printf("unknown n\n");
	break;
    }

See how I left out the breaks on purpose.

In ADA you wouldn't be able to do this without duplicating either the
case-expression (they aren't always simple numbers) or the statements.

-- sanders                The 11th commandment: "Thou shalt use lint"
For every message of the day, a new improved message will arise to overcome it.
Reply-To:  cs.utexas.edu!ibmaus!auschs!sanders.austin.ibm.com!sanders

amull@Morgan.COM (Andrew P. Mullhaupt) (03/11/90)

> or less repetitious (which is not) in a case like this:
> 
>           switch (what_to_do) {
>                     case FIVE_THINGS:
...

This stuff doesn't belong in comp.lang.pascal. It goes in comp.lang.c,
right(?). The fistfight over bill wolfe's complaints about C should
stay in comp.lang.c. If anyone wants to complain about Pascal, then
put it in here. 

BTW - fall through and the 'double duty' break keyword are
definitely examples of C flaws.  If you must, flame me, but in 
comp.lang.c, (OK?)

Later,
Andrew Mullhaupt

peter@ficc.uu.net (Peter da Silva) (03/12/90)

> This stuff doesn't belong in comp.lang.pascal. It goes in comp.lang.c,
> right(?).

No, it doesn't belong in comp.lang.c either. Language lawyers should hold
their court in comp.lang.misc or alt.religion.computers. this thread may have
some slight relevence to comp.software-eng. It doesn't belong in any of
comp.lang.{c,ada}... and even less in comp.lang.{lisp,modula2,pascal}.
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

jclark@SRC.Honeywell.COM (Jeff Clark) (03/13/90)

In article <775@s5.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:

   This stuff doesn't belong in comp.lang.pascal. It goes in comp.lang.c,

Actually, I don't think it belongs in any of these groups.   This "discussion"
seems to have no end and no reasonable resolution since the antagonists
arguments are based on personal opinions, preferences, and emotions.  I've not
seen anyone quote studies of the influence of "human factors" in programming
language design nor has any one proposed such a study as a useful outcome of
this recent flame war (although I must admit I'm wearing out the 'n' key on my
workstation).

comp.lang.religious-wars anyone?

Jeff Clark	Honeywell Systems and Research Center	Minneapolis, MN
inet: jclark@src.honeywell.com		tel: 612-782-7347
uucp: jclark@srcsip.UUCP		fax: 612-782-7438
DISCLAIMER: If you think I speak for my employer, you need serious help ...

sommar@enea.se (Erland Sommarskog) (03/14/90)

I tried thrice mailing this guy, including the path(!) he gave
in his signature. Couldn't IBM afford to be better connected?

Tony Sanders (sanders@sanders.austin.ibm.com) writes:
>How do you do this in ADA?
>
>    switch(n) {
>      case 0:
>	count++;
>      case 1:
>	ocount++;
>      case 2:
>	printf("%d %d\n",count,ocount);
>	break;
>      default:
>	printf("unknown n\n");
>	break;
>    }
>
>See how I left out the breaks on purpose.

Cross you heart, how often in practical programming do you
write such code?  And how often compared to normal switch
statements where an easily elided break would introduce
a simple bug? It might be that I never program in C, but I 
have never felt the need for a fall-through. Also, it seem more
frequent that I first want to execute some common code and
then split the cases further. In this case C's fall-throughs
help you none.

In Ada (please note, it's not all-capital) I would probably
have written the above as:

    IF N = 0 THEN
       Count := Count + 1;
    END IF;
    IF N IN 0..1 THEN
       OCount := OCount + 1;
    END IF;
    IF N IN 0..2 THEN
       Put(Count, 10);
       Put(OCount, 10);
       New_line;
    ELSE
       Put_line("Unknown.");
    END IF;

With a one-line statement for N = 2, I might have chosen to
repeat some lines of code, if the CASE statement better had
illustrated the problem. (And I would probably have made the
same arrangements in C.)
-- 
Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se

lindsay@comp.vuw.ac.nz (Lindsay Groves) (03/14/90)

In article <1004@micropen>, dave@micropen (David F. Carlson) writes:
> What break does is *very* well defined and is no more prone to
misinterpretation
> that any other non-linear control flow statement in any other PL.

A number of people in this discussion (which I haven't reached the end of yet!)
have said things like this, and appear to be suggesting that because something
is well defined there is no excuse for anyone misusing it.  I disagree
with that
and also with the second part of this statement.  There are languages in which
any kind of exit has to explicitly name the construct to be exitted -- so there
is no possiblity of consfusion about which construct the exit/break/etc.
applies
to.

> A multi-case switch is very handy in many situations to reduce identical
> treatments for similar cases.  That you ask the question of the usefulness
> of break-per-case/multiple-cases implies that you haven't sufficient
experience
> with the construct to judge its merits/weaknesses.
> 
> Dijkstra notes that no programming language can prevent a poor
programmer from
> creating bad programs.

So why aren't we all still using FORTRAN (or some older dialect)?  Why did we
all think that unlabelled CASE statements (as in Algol-W and Burroughs Algol)
were a big improvement over computed GOTOs in FORTRAN (which is basically what
the switch in C is), or that the labelled CASE statement (as in Pascal) was
a big improvement over that?  Maybe the whole of the last 30 years of work in
programming language design has been a dream!!!

Lindsay Groves

jaws@chibacity.austin.ibm.com (03/15/90)

Mr Wolf:

C allows you to combine cases that have portions of similiar code
but may have extra lead in code for a specific case:

	switch var:
	case A:
		/* do stuff only case A needs */

	case B:
		/* do stuff case A and case B need done */
		.
		.
		break;

	/* rest of switch */
	

this construct in impossible to do cleanly in almost every language I have
ever seem, especially ADA.

This kind flexiability is what makes C so powerfull, and dangerous. 
You have know what you are doing to do it.


[ Jeff Wilson :: jaws@chibacity.austin.ibm.com                                ]
[ Consultant from Pencom, Inc. at Human Factors, AWD, IBM Austin.             ]
[My comments are wholly my own and as such take them for what they are worth. ]

vanavermaet@kerber.dec.com (03/16/90)

with standard_disclaimer; use standard_disclaimer;

In article <1819@awdprime.UUCP>, jaws@chibacity.austin.ibm.com writes...
>This kind flexiability is what makes C so powerfull, and dangerous. 
>You have know what you are doing to do it.

I think this is a very sensible remark.

O.K., the semantics are well-defined (as may people have pointed out),
but it still IS dangerous. That (IMHO) is a very important factor (and to me, a
reason not to use C).

Peter Van Avermaet