why enums arent my favorite C language feature

utzoo!decvax!harpo!ihps3!houxz!houxi!houxa!houxm!npois!cbosgd!mark utzoo!decvax!harpo!ihps3!houxz!houxi!houxa!houxm!npois!cbosgd!mark
Fri Nov 5 14:12:46 AEST 1982

Why don't I use enums in C?  After all, they are a joy to use in Pascal.
(Too bad the rest of Pascal isn't a joy to use.)  The problem is that
they were thrown into C quickly and without cleanly integrating them into
the language, and at least one compiler (pcc) has a botched implementation.
Consider the following program and what pcc says about it.

enum color {red, blue, green, yellow};

	enum color a, b;
	int c[yellow+1];   /* I'm surprised this isn't an error! */

/*###8 [cc] illegal comparison of enums %%%*/
	if (a < yellow)
		printf("some message\n");

	/* This should work, but doesn't */
	for (b=red;
/*###13 [cc] illegal comparison of enums %%%*/
/*###14 [cc] operands of ++ have incompatible types %%%*/
/*###15 [cc] operands of + have incompatible types %%%*/
/*###15 [cc] illegal indirection %%%*/
			printf("%d\n", c[b]);

	/* This works but it's rediculous */
	for (b=red;
		(int) b <= (int) yellow;
		b = (enum color) ((int) b + 1))
			printf("%d\n", c[(int) b]);

Note that comparison of enums and iteration through them are perfectly
well defined, especially since their integer values are well defined,
but the compiler won't have anything to do with them.  Note also that
these are not warnings, they are fatal errors.

Using enums as array indices is certainly useful in Pascal, but it seems
to have been beyond the aims of the design.  In order to cleanly put them
into C, you need a max operator which would return one higher than the
largest value in the enum (e.g. yellow+1), but this value has type enum color
and an illegal value for this type.  Note the strange array declaration
above and the use of <= in the for loop when < is more traditional C.
(You may think this is a picky point, but I had many bugs in C until I
adopted the programming paradigm that bounds were always one higher then
the largest index, and that loops always went from 0 while < some bound.)

I seem to remember pcc being even fussier when I first tried it out,
generating fatal errors for things like
	enum Boolean {false, true} flag;
	if (flag)
	i = (int) flag;
Either pcc has been improved somewhat since 32V, or my memory is wrong.

Anyway, you can get the same functionality, without any of the protection,
by using #define constants, and you get the extra benefit that such
code will run on a pre-V7 compiler.  This is probably why I still
use such techniques.

More information about the Comp.lang.c mailing list