[comp.lang.c] Number of enums

diamond@jit345.swstokyo.dec.com (Norman Diamond) (01/21/91)

In article <703@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave P. Schaumann) writes:

>C is lacking (as far as I know) a general way to get the last value of an
>enum type.

Yes.

>For instance, suppose I have:
>typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT } days_t ;
>The best I have come up with is to do this:
>#define last_days_t SAT /* Named as last_ ## <enum type name> */

I use:
typedef enum days_t { SUN, MON, TUE, WED, THU, FRI, SAT, NO_OF_DAYS } days_t;
And make sure that new days are added before NO_OF_DAYS.
If I also need LAST_DAY, I use:
#define LAST_DAY  (NO_OF_DAYS - 1)

I wouldn't make a name like "last_days_t" a constant; the name looks like
a type.  Of course, every type name that I named during the past 11 years
is now in the POSIX reserved name space :-(

--
Norman Diamond       diamond@tkov50.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.

dave@cs.arizona.edu (Dave P. Schaumann) (01/22/91)

In article <1991Jan21.133917.18458@cbnews.att.com> jbr@cblph.att.com writes:
|In article <703@caslon.cs.arizona.edu| dave@cs.arizona.edu (Dave P. Schaumann)
|writes:
||C is lacking (as far as I know) a general way to get the last value of an
||enum type.  Having this would aid in the use of enums in two ways:
||[...]
|
|Good point.  Here is what I do:
|
|typedef enum {
|	Thing1 = 0,
|	Thing2,
|	Thing3,
|	  ...
|	NumThings	/* this must always be last */
|} ThingList;
|
|While some may argue that "NumThings" doesn't belong because it isn't logically
|part of the type, I usually find defining things this way solves the problems
|of declaring arrays and looping through each item.  Adding new items is simply
|a matter of inserting them before the "Counter" item.

I got a lot of replies to this through e-mail, mostly proposing this solution
(ie, a special symbol last in the enum-list).  It was also pointed out that my
solution of using last_days_t as a name looks like a type name.  I had thought
of this solution before, but I had discarded it because, as you say, the 
"NumThings" value isn't logically a member of ThingList.  However, given the
difficulties presented by my solution, I think that yours is probably best.

Of course, the optimal solution would be for ANSI to adopt a 'numberof'
with functionality similar to 'sizeof', so that you could say 
numberof(ThingList) to get the number of values.

|  -      _   Joe Brownlee, Analysts International Corp. @ AT&T Network Systems
| /_\  @ / `  471 E Broad St, Suite 1610, Columbus, Ohio 43215   (614) 860-7461
|/   \ | \_,  E-mail: jbr@cblph.att.com     Who pays attention to what _I_ say?
|"Scotty, we need warp drive in 3 minutes or we're all dead!" --- James T. Kirk

Dave Schaumann		|  And then -- what then?  Then, future...
dave@cs.arizona.edu	|  		-Weather Report

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (01/22/91)

On <Jan 21 04:51>, Dave P. Schaumann (dave@cs.arizona.edu ) wrote to All: 


 DPS> For instance, suppose I have:

 DPS> typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT } days_t ;

 DPS> And now I want to declare an array like:
 DPS> float high_temps[<# of days>] ;

  Try for example:

typdef enum CARS { FORD, CHEVY, PLYMOUTH, CARS_MAX };

long registered_vehicles[CARS_MAX];

  Want to add more, no problem...

typdef enum CARS { FORD, CHEVY, PLYMOUTH, FERARRI, YUGO, CARS_MAX };
 

mcdaniel@adi.com (Tim McDaniel) (01/23/91)

My apologies: the following discussion, about numberof(), is not
appropriate to comp.lang.c.  We don't have alt.cfutures or suchlike.

dave@cs.arizona.edu (Dave P. Schaumann) writes:
   Of course, the optimal solution would be for ANSI to adopt a 'numberof'
   with functionality similar to 'sizeof', so that you could say 
   numberof(ThingList) to get the number of values.

While this construct may be useful in certain cases, I must point out
that enum constants are not required to be consecutive.  There are
often good reasons for avoiding such.  There is existing code that
depends on it.

Therefore, there must be a comment at the site of the enum declaration
ANYWAY, warning the next editor that the enum constants must remain
consecutive from zero.  If the comment is ignored, the code will
break.  In such cases, you might as well add the line
   , maxDays /* used for subscript bounds, etc. */
and then there's no need for "numberof()".

(Although it hasn't been suggested yet, I think that adding
"consecutiveenum" and "numberof" would be gross overkill.  I believe
that, if the problem can be solved with a comment and reasonable
convention in just one place, there's no need for a larger solution.)

--
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Work phone: +1 313 973 1300                        Home phone: +1 313 677 4386
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel

chip@tct.uucp (Chip Salzenberg) (01/24/91)

According to dave@cs.arizona.edu (Dave P. Schaumann):
>Of course, the optimal solution would be for ANSI to adopt a 'numberof'
>with functionality similar to 'sizeof', so that you could say 
>numberof(ThingList) to get the number of values.

Hardly.  Given:

    typedef enum {
	CORGE = -100, QUUX = -50,
	LARRY = 1, MOE = 2, CURLY = 4, JOE = 9,
	EX_PARROT = 32767
    } PLUGH;

Of what use would numberof(PLUGH) be?
-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
       "If Usenet exists, then what is its mailing address?"  -- me
             "c/o The Daily Planet, Metropolis."  -- Jeff Daiell

dave@cs.arizona.edu (Dave P. Schaumann) (01/24/91)

In article <279DC67C.6ABD@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
>According to dave@cs.arizona.edu (Dave P. Schaumann):
>>[suggests the new operator 'numberof' would be A Good Thing]
>
>Hardly.  Given:
>
>    typedef enum {
>	CORGE = -100, QUUX = -50,
>	LARRY = 1, MOE = 2, CURLY = 4, JOE = 9,
>	EX_PARROT = 32767
>    } PLUGH;
>
>Of what use would numberof(PLUGH) be?

Indeed.  What use would it be?  I intended that the numberof operator would be
useful for non-initialized enums only.  If the programmer used the numberof
operator on PLUGH, the result shouldn't necessarily be useful.

Let me give a more precise definition of what I think 'numberof' should do,
to put to rest some questions I have been getting.

DEFINE numberof(enum typename) to return the value of the last name in typename
       incremented by 1.  This would be a compile-time operator like 'sizeof'.

Thus, the operaton is well-defined over all possible enum definitions, and
gives a useful value for default-valued enums.

Frankly, I don't really care what happens in the case of an initialized-enum
type.  The only thing that I would really want is for it to be well defined,
and easy to implement.

Probably the most serious objection I recieved to this operator was "does C
really need another operator?"  The only defense I can offer for having
numberof() instead of using a special final enum name is that the enum is
syntactically and (IMO) conceptually cleaner.  It is true that it offers no
new functionality to the language, but I would argue that it is easier to
understand "int a[numberof(enum foo)]" at a glance than it is to understand
"int b[NUMBER_OF_FOO]".  In the first case, all you need to understand is
the operation of 'numberof'.  In the second case, you also to understand the
programmer's style and naming conventions.


>Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>

Dave Schaumann		|  And then -- what then?  Then, future...
dave@cs.arizona.edu	|  		-Weather Report

peter@pdact.pd.necisa.oz (Peter Miller) (01/25/91)

In article <279DC67C.6ABD@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
>According to dave@cs.arizona.edu (Dave P. Schaumann):
>>[suggests the new operator 'numberof' would be A Good Thing]
>
>[counter example given]

This reminds me of my favorite C extension, suggested
long a go by Tim Long: operators called "minof" and "maxof", which take
an argument similar to the "sizeof" operator.  Thus "minof(enum PLUGH)"
would return the minimum value of any of the PLUGH enum tags,
similarly "maxof(enum PLUGH)" would return the maximum value of any of the
PLUGH enum tags.

These operators have even more uses,
portions of limits.h become the same for all machines:
	#define SCHAR_MIN minof(signed char)
	#define SCHAR_MAX maxof(signed char)
	#define UCHAR_MAX maxof(unsigned char)
	#define CHAR_MAX maxof(char)
	#define CHAR_MIN minof(char) 
	#define SHRT_MAX maxof(short)
	#define SHRT_MIN minof(short)
	#define USHRT_MAX maxof(unsigned short)
	#define INT_MAX maxof(int)
	#define INT_MIN minof(int)
	#define UINT_MAX maxof(unsigned int)
	#define LONG_MAX maxof(long)
	#define LONG_MIN minof(long)
	#define ULONG_MAX maxof(unsigned long)

Note that this works without #ifdef's whether "char" defaults
to "signed" or "unsigned".



Regards
Peter Miller	UUCP	uunet!munnari!pdact.pd.necisa.oz!pmiller
		ACSnet	pmiller@pdact.pd.necisa.oz
/\/\*		CSNET	pmiller@pdact.pd.necisa.oz.au
Disclaimer:  The views expressed here are personal and do not necessarily
	reflect the view of my employer or the views or my colleagues.
D