[comp.lang.c] enum type

smiller@umn-cs.UUCP (Steven M. Miller) (08/20/87)

I've never used the enum type in C before and am having some minor struggles
with it.

I've seen several examples with enum types where the type is used as 
below.

enum color { yellow, green, red };

main()

	enum color marker;

	for (marker = yellow ; marker != red ; marker++)
	{
		/* some code here */
	 }
}

The compilers on the Sun and on a Honeywell x20 both complain that
the operands of ++ in the for line are of incompatible types.

Is there any way to make the above work without a lot of casts?


I've also found that lint complains heavily about the following use of
enums.

main()
{
	enum color pen;

	func( &pen );

}

func( marker )
enum color *marker;
{
  /* some code here */
}


Here lint complains that the the argument to func is used inconsistently.
The code runs fine, but why does lint complain? 


By the way does the ANSI C standard do anything new with enums? like
provide succ(), pred(), lower(), and upper() functions that operate
on enum types?

guy%gorodish@Sun.COM (Guy Harris) (08/21/87)

> 	enum color marker;
> 
> 	for (marker = yellow ; marker != red ; marker++)
   ...
> 
> Is there any way to make the above work without a lot of casts?

In general, no.

> 	enum color pen;
> 
> 	func( &pen );
   ...
> func( marker )
> enum color *marker;
> 
> Here lint complains that the the argument to func is used inconsistently.
> The code runs fine, but why does lint complain? 

Because it has a bug in it.  The problem is that PCC eventually treats "enum"s
as appropriately-sized integral objects ("char", "short", "int", "long").
This means that pointers to "enum"s get converted to pointers to that integral
object type, so it thinks "func" is getting passed a "char *".

This was fixed in our 3.2 release.  That fix, more or less, has been posted to
"comp.bugs.4bsd" and "comp.bugs.sys5".

> By the way does the ANSI C standard do anything new with enums? like
> provide succ(), pred(), lower(), and upper() functions that operate
> on enum types?

Yes, it does something new.  It does not, however, make "enum"s more
full-fledged data types, with "succ", "pred", etc.  operators.  Instead, it
makes "enum"s *more* like "int"s, so that the "marker++" above would be
permitted, and so that they may be used in pointer arithmetic (and thus may be
used as array subscripts).  One hopes they do not intend to forbid compilers to
generate warnings when "enum" type mismatches are detected, as such mismatches
are usually errors.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

karl@haddock.ISC.COM (Karl Heuer) (08/21/87)

In article <2048@umn-cs.UUCP> smiller@umn-cs.UUCP (Steven M. Miller) writes:
>The compilers on the Sun and on a Honeywell x20 both complain that
>the [enum] operands of "++" ... are of incompatible types.
>Is there any way to make the above work without a lot of casts?

Some compilers are strict about enums, others are lax.  Yours seems to be the
former.  I think you'll need to either change your enums to ints, or use
casts.  You could hide it with "#define bump(x) (x=(enum color)((int)(x)+1))",
if you only have one type of enum to worry about.

>I've also found that lint complains heavily about [enums as arguments]

That's a well-known lint bug.

>By the way does the ANSI C standard do anything new with enums? like
>provide succ(), pred(), lower(), and upper() functions that operate
>on enum types?

It asserts essentially that enums are ints, so you can use "++", "--", etc.

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

gwyn@brl-smoke.ARPA (Doug Gwyn ) (08/21/87)

In article <2048@umn-cs.UUCP> smiller@umn-cs.UUCP (Steven M. Miller) writes:
>By the way does the ANSI C standard do anything new with enums? like
>provide succ(), pred(), lower(), and upper() functions that operate
>on enum types?

No, X3J11 decided that enums have to act as integral types, so
one can use ++ etc. on them.  If you want a general set or sequence
data type, you'll have to develop a package that implements it.

vic@zen.UUCP (Victor Gavin) (08/22/87)

I have recently been using Microsoft C 4.00 and came across a situation
involving enums which the compiler complained about but which had worked
on the other C compiler I use regularly (HP 9000 series 500).

I have a boolean decleration thus

enum BOOLEAN { false = 0, true = 1};
typedef enum BOOLEAN boolean;


and when used so

  boolean fini = false;
  
  
  while ( !fini )
  {...}


the MSC compiler complains


   "'!' : illegal with enums" and
   "'!' : bad right operand"


What I'd like to know is if I'm doing something wrong or if the MSC
compiler is goofy.

		vic
--
Victor Gavin						Zengrange Limited
vic@zen.co.uk						Greenfield Road
..!mcvax!ukc!zen.co.uk!vic				Leeds LS9 8DB
+44 532 489048						England

kent@xanth.UUCP (Kent Paul Dolan) (08/23/87)

In article <6311@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <2048@umn-cs.UUCP> smiller@umn-cs.UUCP (Steven M. Miller) writes:
>>By the way does the ANSI C standard do anything new with enums? like
>>provide succ(), pred(), lower(), and upper() functions that operate
>>on enum types?
>
>No, X3J11 decided that enums have to act as integral types, so
>one can use ++ etc. on them.  If you want a general set or sequence
>data type, you'll have to develop a package that implements it.

(sorry Karl, I couldn't wait)

Looks to me like whoever added enums to C got a bit carried away when
they included intiializers.  C already had a very nice and well
#defined facility for named constants; the one created by allowing
initializers with enum is redundant, and seems (from postings running
back a month or so ago) to have created a headache for the standards
process.

Enums are a really nice idea, but as used in other languages, they
provide a facility for replacing (usually integer) values with names,
where the values _made_no_sense_, and only the fact that they could be
distinguished (and possibly had an order) was important.

C enums seem to have foundered by mixing two actually incompatible
constructs in an effort to be "cute".  Is it too late to remove this
(to me blunder) from the definition of C?

Kent, the man from xanth.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (08/24/87)

In article <2238@xanth.UUCP> kent@xanth.UUCP (Kent Paul Dolan) writes:
>C enums seem to have foundered by mixing two actually incompatible
>constructs in an effort to be "cute".

It was not an effort to be "cute".  Don't you think X3J11 is aware
of the problems with C enums?  Go play with your Ada and leave us
alone.

jagardner@orchid.UUCP (08/25/87)

In article <2238@xanth.UUCP> kent@xanth.UUCP (Kent Paul Dolan) writes:
>
>Looks to me like whoever added enums to C got a bit carried away when
>they included intiializers.  C already had a very nice and well
>#defined facility for named constants; the one created by allowing
>initializers with enum is redundant, and seems (from postings running
			   ^^^^^^^^^
>back a month or so ago) to have created a headache for the standards
>process.

#define XX_SOMETHING  1
     ....
#define XX_ELSE  295

Now insert a new definition at position 42. This requires changing all
those #defines. enums make it easy (you can also say XX_LAST at the end
and use that as the number of things in the enum (if you don't use =)).

David Tanguay

rlk@chinet.UUCP (Richard Klappal) (08/26/87)

In addition to automatic generation of values (if desired), without
accidental duplicate values, enums give lint the ability to check
consistent usage.

	Programming commandments (some)

	1. Make it work.
	2. Use lint
	3. Make it maintainable
	4. Use lint
	5. Make it legible
	6. Use lint
	7. Make it portable
	8. Use lint.


-- 
---
UUCP: ..!ihnp4!chinet!uklpl!rlk || MCIMail: rklappal || Compuserve: 74106,1021
      ..!ihnp4!ihu1h!rlk
---