problems/risks due to programming language

Karl Heuer karl at haddock.ima.isc.com
Tue Feb 27 09:02:13 AEST 1990


I'm redirecting followups to comp.lang.misc.

In article <5479 at ur-cc.UUCP> Michael Sullivan writes:
>[A lot of strawman arguments]

I don't think anybody is seriously arguing the position that you seem to be
attacking.  I also don't know how closely my position matches that of the
other participants in this debate, but I'll state mine as a series of claims
for you to agree with or rebut as you like.

It's meaningless to say "the `break' keyword is {good,bad}"; you have to have
an alternative to compare against.  I will use the notation `C with feature X'
to mean `a hypothetical language which is a lot like C but which has feature
X'; then we can make statements like `C with X would be a better tool than C'.

I am not arguing that C should be changed in this regard (except by adding
warning messages where appropriate).  Thus, the existence of a large body of
code written in C-as-it-is-today is not a factor in such comparisons.

We need to distinguish between keywords and the operations they denote.  It
turns out to be useful to distinguish two operations, which I will call
`break-switch' and `break-loop', both of which are denoted by the keyword
`break' (depending on context).  I will use the term `fall-through' to denote
the operation of flowing from the end of one case into the beginning of the
next one; this operation is denoted in C by the absence of a `break' keyword
in reachable flow at the end of a case block.

Claim 0.  Much use of fall-through in C is simply attaching several cases to a
single action.  (In fact, this is the `positive side' you quoted from the Holy
Scriptures.)  Some other languages achieve this by allowing multiple values to
be associated with a single case label, instead.  Thus, C with multiple valued
cases would not need fall-through nearly as often.

Claim 1.  A break-switch is rarely needed at any point other than at the end
of a case block.  At the end of a case block, break-switch is needed much more
often than fall-through.

Claim 2.  As a general principle, if there is a default action it should be
the most common of the alternatives.  This tends to minimize certain kinds of
user errors.

Definitions.  Let `CX' be the language C with multiple valued cases, with
automatic break-switch at the end of each case block, and with the `break'
keyword denoting only the break-loop operation.  `CX with jumpcase' is CX
with an explicit keyword to denote the fall-through operations (overriding the
default behavior of an automatic break-switch).

Claim 3.  CX with jumpcase would be better than C.

Claim 4.  CX itself would be better than CX with jumpcase (and hence better
than C); the extra keyword doesn't buy you enough to be worth adding, and it
would destroy the commutativity of case blocks, which is a useful property of
CX.

Claim 5.  Because C, not CX, is what we actually have, and because of what I
said in Claim 1, a useful feature of C compilers and/or checkers (lint) is the
ability to produce a warning if (a) a `break' keyword denoting a break-switch
operation appears anywhere other than at the end of a case block, or (b) a
(reachable) fall-through operation occurs at the end of a case block.

Claim 6.  In the case of lint, at least, such warnings should be enabled by
default.  There should be lintpragmas (e.g. /*SWITCH*/, /*FALLTHROUGH*/) that
can selectively disable them.

Karl W. Z. Heuer (karl at ima.ima.isc.com or harvard!ima!karl), The Walking Lint



More information about the Comp.lang.c mailing list