Is there a way to determine the highest value of a enum?

I'm using the following construct:

enum token{SOE, ADD, SUB, MUL, DIV, DIG, X, RP, LP, EOE, ERR, LT};
const char *tStr[LT] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};

I wonder if there is any way around using an actual value from the enum to dimension the array. That is some mechanism to tell the highest value in the enum like MAX(token) or similar. The compiler surely knows but how can i get it to reveal that information?

The way you've done, with a dummy marker, it is the usual way, IIRC

Since you are defining them, create your own:

#define NUM_TOKENS (12)

Just remember to change it if you add a token.

Note: That your trick won't work if you have changed the values of the enums.

KeithRB:
Since you are defining them, create your own:

#define NUM_TOKENS (12)

Just remember to change it if you add a token.

Better to just add NUM_TOKENS as the last item in the enum. Otherwise, you run the risk of NUM_TOKENS being wrong when you add to the list. enums are always defined in sequence, starting at 0.

Regards,
Ray L.

Wrong, you are free to change the values of the enum like the following:

enum boys {Bill = 10, John = Bill+2, Fred = John + 2};

I could of course get rid of the dummy token by doing this:

enum token{SOE, ADD, SUB, MUL, DIV, DIG, X, RP, LP, EOE, ERR};
const char *tStr[ERR+1] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};

But there seems to be no way of getting the highest value without using members of the enumeration. Am i right about that?

KeithRB:
Wrong, you are free to change the values of the enum like the following:

enum boys {Bill = 10, John = Bill+2, Fred = John + 2};

Yes, you are free to FORCE specific values, but if you do that, then what use is knowing the MAX value? And note the OP is NOT forcing the values.

You're suggesting you would not be smart enough to take that into account when defining the max value, but you would be smart enough to always remember to update the #define? What I suggested will work 99% of the time, without the user having to do anything more than update the enum. Your approach will work ONLY if the user correctly defines, and remembers to update his explicit define, EVERY time he changes the enum. Which is more likely to be robust over time?

Your approach also opens the door to creating enums with holes in the sequence, and even two, or more, different enum symbols having the SAME value. How much fun will that be to debug?

Regards,
Ray L.

nilton61:
I could of course get rid of the dummy token by doing this:

enum token{SOE, ADD, SUB, MUL, DIV, DIG, X, RP, LP, EOE, ERR};

const char *tStr[ERR+1] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};




But there seems to be no way of getting the highest value without using members of the enumeration. Am i right about that?

If you don't want to have to count the enums and manually set the MAX value each time, that is correct.

Regards,
Ray L.

Since you're populating it, why do you need to dimension the array at all?

const char *tStr[] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};

wildbill:
Since you're populating it, why do you need to dimension the array at all?

const char *tStr[] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};

Because i want the compiler to check the consistency between the enum and the array. I want to ensure there is a string reprensentation for every member in the enum and get a compile error if i happen to forget one.

Also it was a general question, not a specific one since there are clearly more instances where you need to know the number of members or highest value of an enum. I think this is possible in java c# and vb

Because i want the compiler to check the consistency between the enum and the array. I

You could probably automate all of this with clever use of the preprocessor's ## stringify operator and some multiple #includes

See: http://www.pixelbeat.org/programming/gcc/static_assert.html

Example:

enum token{SOE, ADD, SUB, MUL, DIV, DIG, X, RP, LP, EOE, ERR, LAST};
const char *tStr[] = {"SOE", "ADD", "SUB", "MUL", "DIV", "DIG", "X", ")", "(", "EOE", "ERR"};

/* Note we need the 2 concats below because arguments to ##
 * are not expanded, so we need to expand __LINE__ with one indirection
 * before doing the actual concatenation. */
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
#define ct_assert(e) enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }

// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

// The condition we want to test
ct_assert(ARRAY_SIZE (tStr) == LAST);

void setup () { }
void loop () { }

This raises a compile error if the number of elements in tStr is not equal to LAST.