[comp.lang.c] How do you document breakless cases

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (06/29/88)

Thanks very much to the 21 writers that responded to my
request.  Here are the results for each of the categories.
Some writers commented on each while most commented on only
one method, which explains why the totals are goofy.
This was hard to summarize, but here goes.  Draw your
own conclusions.

If you want to see the unedited texts send me email (sorry
I was late summarizing, I felt crummy Tuesday night).

1) do nothing

1 writer said this was acceptable since it is a documented
language feature and that there shouldn't be many cases
where it wasn't clear what was going on.

2 writers said this was "poor", one said it was "out of the
question", and another said "No, no, no :-)."

2 writers explicitly said this was acceptable in the
case (pun intended) of "multiple cases" since it is
clear that they all go together.  For example:

	case 'a':
	case 'e':
	case 'i':
	case 'o':
	case 'u':
		vowel();
		break;
	

2) use the "lint-like" comment /* FALLTHROUGH */
   or /* FALLTHRU */ or /* FLOWTHRU */

This was the most preferred solution, however, the comments
used varied widely.  The general sentiment was that if lint
or some other filter would catch this type of comment then
people would use it.  Two people said they did not like
this technique, but didn't give specifics.  One didn't like it
and said that it didn't really tell you enough and prefered #3
when the sentence said *why* the fall through occurred.

	5 /* FALLTHROUGH */
	4 /* no break */
	1 /*FALLTHROUGH*/
	1 /* FALL THROUGH */
	1 /* fall... */
	1 /* fall through... */
	1 /* fall into case XYZZY... */
	1 /* fall through */
	1 /* FALLTHRU */
	1 /* fallthrough */
		if the last statement before a case isn't one of
			return
			exit
			abort
			etc.
	1 /* and fall through */
	1 /* FALLTHROUGH */ only if lint or some other filter checks
		this
	1 /*   !!! DANGER !!! MANHOLE !!!  */
	1 /*   !! WARNING !! CASE WITHOUT BOTTOM !!   */

(A few writers implied some lints caught the /* FALLTHROUGH */ comment).


3) use a sentence in a comment
   eg /* a break is not used in this case */

The third solution didn't get any support as written.  However,
everyone thought that the comment should be more descriptive to
the reader, eg it should say why the fall through is needed etc.
Two writers expressed concern about the amount of typing that
this required (perhaps it was my example that was the real problem).
One writer said if this kind of sentence was going to be used
you may as well use FALLTHROUGH, since lint will ignore the sentence.


4) use a define, eg #define flowthru /* nothing */
   flowthru;

Six writers said this was bad because it constituted language
syntax redefinition and/or would slow down the reader.  One
writer said this was not as good as #2.

Two writers supported this technique.  They used:

1 #define flowthru /* nothing */

1 #define Case  break ; case
  #define Default break ; default
  #define Orcase case ;

  The ordinary kinds of things become

  Case 'x' : Orcase 'y' : ...
  Case 'z' : ...

  A fallthrough (other than the trivial ones above) is so uncommon
  in my style that I would always insert a comment explaining why the
  code is written this way.

-- 
Larry Cipriani, AT&T Network Systems and Ohio State University
Domain: lvc@tut.cis.ohio-state.edu
Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (strange but true)

sullivan@vsi.UUCP (Michael T Sullivan) (07/01/88)

In article <16607@tut.cis.ohio-state.edu>, lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes:

> 	1 /* fallthrough */
> 		if the last statement before a case isn't one of
> 			return
> 			exit
> 			abort
> 			etc.

return is different that exit and abort.  Lint knows that return isn't coming
back, wheras exit and abort are just functions.  I ran into this the other
day where my switch had all cases and default that returned and one that exited.
Lint complained about the one that exited with a "function has return and
return(e)" type of message.  I put a /*NOTREACHED*/ after the exit and lint
was much happier.

-- 
Michael Sullivan			{uunet|attmail}!vsi!sullivan
V-Systems, Inc.  Santa Ana, CA		sullivan@vsi.com
ons, workstations, workstations, workstations, workstations, workstations, work

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (07/05/88)

In article <739@vsi.UUCP>, sullivan@vsi.UUCP (Michael T Sullivan) writes:
> In article <16607@tut.cis.ohio-state.edu>, lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes:
>
> >     1 /* fallthrough */
> >         if the last statement before a case isn't one of
> >             return
> >             exit
> >             abort
> >             etc.
>
> return is different that exit and abort.  Lint knows that return isn't coming
> back, wheras exit and abort are just functions.  I ran into this the other
> day where my switch had all cases and default that returned and one that exited.
> Lint complained about the one that exited with a "function has return and
> return(e)" type of message.  I put a /*NOTREACHED*/ after the exit and lint
> was much happier.

Our version of lint has both a /*FALLTHROUGH*/ directive for the switch
statement, and a /*GOTO*/ directive for external declarations.
e.g. <stdlib.h> should contain:  extern /*GOTO*/ exit();
then any program that includes <stdlib.h> will lint correctly
and never need /*NOTREACHED*/.  The following lints cleanly:

    extern /*GOTO*/ exit();
    extern /*GOTO*/ abort();

    main(argc)
    {
        switch (argc) {
            case -3:
            case -2:
            case -1:
                abort();
            case 0:
                return 0;
            case 1:
                ++argc;
                /*FALLTHROUGH*/
            case 2:
                ++argc;
                exit(argc);
            default:
                return 42;
        }
    }


If anyone else implements these, it would be nice if they used the
same keywords instead of inventing yet another name.