[comp.lang.c] Results of duplicate-case-in-nested-switch survey

chase@orc.olivetti.com (01/27/89)

Here's a summary of how different C compilers reacted to a program
(repeated at end of message) containing a duplicate case within a
nested switch statement.  I was prompted to do this because most
of the compilers accessible to me here either didn't report the error
or reported lots of bogus errors.  As it turns out, this appears to be
(usually) a PCC bug (should I be surprised?).  What looks like a
likely fix is also included.

(gcc 1.29 gets it right, gcc 1.32 is mute, SunOS 3.5 and 4.0 cc 
 each report two non-existent errors in addition to identifying the
 switch statement containing the duplicate case.)
----------------
RAMontante <bobmon@iuvax.cs.indiana.edu>
Turbo C v2.0 gets it "right", i.e. it agrees with gcc v1.29 that there
is a "duplicate case value in line 13" (not quite the exact wording).
----------------
Lee Fisher, Microsoft, leefi@microsof.UUCP, leefi%microsof@uw-beaver.MIL
Here are the results of using the Microsoft C compiler version 5.1:
  Microsoft C compiler 5.1 for DOS and OS/2, cl -W3:
  test.c(2) : warning C4103: 'foo' : function definition used as prototype
  test.c(13) : error C2053: case value 5 already used
----------------
Bill Smith, wsmith@cs.uiuc.edu
Encore's Multimax current OS's compiler says:
  "/tmp/wsmith/a.c", line 13: Duplicate case
----------------
vsi!friedl@uunet.UU.NET
AT&T's Issue 4 C compilers for the 3B2 do it wrong too.  I hear
from reliable sources that this has been fixed in the next
release.

and
Tony Hansen, hansen@pegasus.att.com
Unix System V release 3.2.1 on a 3B2 reports:
  "junk.c", line 15: duplicate case in switch, 5
  "junk.c", line 16: duplicate case in switch, 5
  "junk.c", line 17: duplicate case in switch, 0
----------------
John Woods, ames!harvard!wjh12!frog!john
Results for the Green Hills C compiler:
  Test.c:
  C-68000U 1.8.0 Copyright (c)1985,1986 Green Hills Software, Inc.
  "Test.c", line 13: Duplicate case
----------------
chemabs!chemabs!lwv27@cis.ohio-state.edu (Larry W. Virden)
The following is the output from Ultrix 2.3's 2 c compilers.  The first
is based on a BSD compiler, though I was in 'system v' mode when executing
it - the second is the Ultrix VMS-compatible vcc compiler.
  UNIX16 (212) $ cc test.c
  "test.c", line 15: duplicate case in switch, 5
  "test.c", line 16: duplicate case in switch, 5
  "test.c", line 17: duplicate case in switch, 0
  UNIX16 (213) $ vcc test.c
  "test.c", line 13: %E-DUPCASE, Duplicate case label value "5".
  "test.c", line 19: %I-NOBJECT, No object file produced.
  "test.c", line 19: %I-SUMMARY, Completed with 1 error(s), 0 warning(s), and
                  1 informational messages.
  UNIX16 (214) $ uname -a
  ULTRIX-32 UNIX16 2.2 0 VAX
  UNIX16 (215) $ 
Note that the OS really is 2.3, even though uname says 2.2 ... sigh.
----------------
Michael Greim <greim%sbsvax.informatik.uni-saarland.dbp.de@RELAY.CS.NET>
SIEMENS PC-MX2 running SINIX v2.1 (SYS 3 derived):
  $ cc -c -W3 test16.c >& mist01
  c1:
  test16.c    7: [warning]:  flow between cases
  test16.c   10: [warning]:  flow between cases
  test16.c   13: [error]:    duplicate case: 5
  test16.c   14: [warning]:  flow between cases
  errors: 1, warnings: 3 in pass 1
  $
(-W3 turns on the warnings)
----------------
Chip Rosenthal     chip@vector.UUCP
Believe it or not ... Microsoft C (which is what the XENIX cc is) does:
    /tmp/foo.c(13) : error 53: case value 5 already used
----------------
Mark Grand of Ashton-Tate in Walnut Creek reports that the
Metaware CC compiler correctly identifies both lines involved
in the duplication.  (Anyone have a mail address for these people?)
----------------
and (already posted to netnews)
jeff@unh.UUCP (Jeffrey E. F. Friedl)
[offending CC's are PCC derivatives, here's how to fix it if you have
source]

I fixed mine this way (your filenames/function names may vary):
In cgram.y, function swend(), near the end is a sequence much like:

	if (there is a duplicate case) {
		report_error("duplicate case in switch, %d", value);
		return;
	}

	dosomethinghere();
	swp = swbeg-1;	/* this "pops" this switch from the switch-stack */
    } /* end of function */
	
Just copy the "swp=swbeg-1" line to after the error call.  All will be happy.
----------------

In summary, PCC derivatives get it wrong unless fixed, for GCC it
depends upon the release of the compiler (Doug Schmidt reports it is
fixed for the next (1.33) version of GCC, though 1.33 was not on prep
today when I looked just now), and every other compiler reported gets
it right, and (as a Bonus Treat) reports the offending line (not just
the offending switch statement).

(The test program:)
----------------
 1:	foo(i,j,k)   int i,j,k;
 2:	{
 3:	  int r = 0;
 4:	  switch (i)
 5:	    {
 6:	    case 1: r = i;
 7:	    case 2: switch (j)
 8:		{
 9:		case 3: r = j;
10:		case 4: switch (k)
11:		    {
12:		    case 5: break;
13:		    case 5: r = k; /* line 13, for reference */
14:		    case 6: break;
15:		    }
16:		}
17:	    }
18:	  return r;
19:	}
----------------

David Chase
Olivetti Research Center, Menlo Park