Jim Fell
Jim Fell

Reputation: 14256

Enumerated Type Value Not Comparing Correctly

I'm writing some C code for an embedded application, and I've run into a problem wherein a compare against an enumerated value is not being executed correctly. Take the following code snippet, for example:

typedef unsigned int UINT16;
typedef enum enum_items_tag
{
   ITEM_1,
   ITEM_2,
   ITEM_3,

   /* ... */

   ITEM_918,
   MAX_ENUM_ITEMS
} enum_items_t;

UINT16 n;

for ( n = 0; n < MAX_ENUM_ITEMS; n++ )
{
   // Do something
}

The code executes as expected, until n is incremented to equal MAX_ENUM_ITEMS, at which time the compare fails, and execution continues within the loop (when it should have exited). I've done things like this in the past without any problems.

I've tried re-typing n as enum_items_t (i.e. declaring n as "enum_items_t n"), as well as type casting MAX_ENUM_ITEMS as UINT16. The only other thing I can think of at this point is that maybe there is an issue with the number of items there are in my enumerated type (919). Does anyone know if there are such constraints on enumerated types? I'm using a GCC based compiler. Or, if you have any other ideas, it would be much appreciated. Thanks.

Upvotes: 1

Views: 351

Answers (4)

Calyth
Calyth

Reputation: 1673

Try starting your loop with n = ITEM_1?

Upvotes: 1

DarthNoodles
DarthNoodles

Reputation: 370

I'd print out MAX_ENUM_ITEMS just to make sure that the value of it is what you think it should be. With a list that long it would not be difficult to messs it up.

Upvotes: 0

Philip Davis
Philip Davis

Reputation: 276

Could it be an off-by-one error? I would expect that gcc starts enums at 0... but you say you saw the value increase to 919 while debugging. So that makes me think either you've got an extra value in the enum by accident or the enum values are 1-based just like the naming scheme implies.

If ITEM_1 == 1 then either start your n at 1... or change the value of MAX_ENUM_ITEMS as follows:

typedef enum enum_items_tag
{
   ITEM_1,
   ITEM_2,
   ITEM_3,

   /* ... */

   ITEM_918,
   MAX_ENUM_ITEMS = ITEM_918
} enum_items_t;

Upvotes: 4

Pavel Minaev
Pavel Minaev

Reputation: 101565

ISO C is rather vague on internal representation of enums, but one thing it does guarantee is that the type used should be wide enough to handle all values, so long as you don't exceed the limit for int. Unless you're using some compiler switch to enable implementation-specific behavior which sets enum representation to something fixed (like a char).

In any case, try printing out sizeof(enum_items_t) and see what you get.

Also, int should be at least 16 bits wide per ISO C, but on embedded platforms (and especially DSPs) you run into all kinds of weird things, so check if int is really 16-bit, as well.

Upvotes: 0

Related Questions