0

if I have enum:

typedef enum
{
   A= 0,
   B= 1,
   C =2,
   D= 4,
   E= 6,
   F= 8,
   G= 10,

   MAX_ELEMENTS
}my_enum

How can I declare the number of elements within enum without one element?

something like this:

uint8 enum_numb_elements = MAX_ELEMENTS - 1

This is not a good practice to do arithmetic operation on enums. Is there an other way?

JohnDoe
  • 825
  • 1
  • 13
  • 31
  • 2
    What does `enum_size` mean? `sizeof` would give a very different answer from `MAX_ELEMENTS - 1`. – n. m. could be an AI Apr 18 '17 at 09:30
  • @n.m. I mean the number of elements in enum – JohnDoe Apr 18 '17 at 09:32
  • The number of elements in an enum is different from the largest value in the enum. Do you need the number of discrete things the enum can represent or the largest value in the enum? – djgandy Apr 18 '17 at 09:33
  • @n.m. Yes, exactly the number of discrete things in enum. – JohnDoe Apr 18 '17 at 09:35
  • 1
    Have you checked [\[ this \]](http://stackoverflow.com/a/712487/1620779) answer? – sjsam Apr 18 '17 at 09:37
  • 4
    Neither gives the number of elements in your enum. The only way to get this number is to count the elements by hand. – n. m. could be an AI Apr 18 '17 at 09:38
  • 2
    @sjsam That won't work with the sparse enum like this question has. – user694733 Apr 18 '17 at 09:40
  • @user694733 of course it won't as the other commenter has already mentioned.. – sjsam Apr 18 '17 at 09:42
  • 1
    @kingkong I think you would be better off defining the wider problem you are trying to solve and why your enums have gaps etc. There may be a better way to solve your problem. – djgandy Apr 18 '17 at 09:42
  • In C a variable of an enumerated type can hold any value of some integral type (char or int or unsigned int...) . The exact type depends on the enum itself and the implementation but in any case the number of different values is at least 127. – n. m. could be an AI Apr 18 '17 at 09:48

2 Answers2

4

You can define it, sort of, but it involves some boiler-plate that isn't all too pleasant, and pollutes the global/tag namespace a lot/bit.

If you leverage the notorious X macros for the job, it would look like this:

#define LIST_OF_ENUM_IDS \
    X(A, 0) \
    X(B, 1) \
    X(C, 2) \
    X(D, 4) \
    X(E, 6) \
    X(F, 8) \
    X(G, 10)

#define X(id, val) \
  id = val,

typedef enum
{
  LIST_OF_ENUM_IDS
} my_enum;

#undef X

#define X(id, val) id##_impl_helper,

enum my_enum_impl_helper__ {
  LIST_OF_ENUM_IDS
  MY_ENUM_MAX_ELEMENTS
};

#undef X

Live example: On Ideone


Alternatively, some shops will instead rely on bold comments and code reviews to catch such things:

/********************************************
*
**
*** ATTENTION! Remember to bump MAX_ELEMENTS
*** should you add new values to the enum
**
*
********************************************/
typedef enum
{
   A= 0,
   B= 1,
   C =2,
   D= 4,
   E= 6,
   F= 8,
   G= 10,

   MAX_ELEMENTS = 7 /// Bump this if you add new values!
}my_enum;

Which can work not all too bad, despite the human factor.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
0

I prefer to keep enums contiguous to exploit the 'features' of C..

typedef enum
{
   A,
   B,
   C,
   D,
   E,
   F,
   G,
   MAX_ELEMENTS
} my_enum;

int element_array[MAX_ELEMENTS] =
{
    0,
    1,
    2,
    4,
    6,
    8,
    10
};

Given this construct, NUM_ELEMENTS adjusts automatically if you add/subtract enums, and you can use my_elem in for loops, etc. The major issue of concern is that you need to remember to maintain element_array in conjunction with my_enum when you add or remove enums.

A for loop example

my_elem elem;
for (elem = (my_elem)0; elem < MAX_ELEMENTS; elem++)
{
    printf("The value of element %d is %d\n", elem, element_array[elem] );
}