Number of elements in an enum

CEnums

C Problem Overview


In C, is there a nice way to track the number of elements in an enum? I've seen

enum blah {
    FIRST,
    SECOND,
    THIRD,
    LAST
};

But this only works if the items are sequential and start at zero.

C Solutions


Solution 1 - C

If you don't assign your enums you can do somethings like this:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

NumberOfTypes will evaluate to 3 which is the number of real types.

Solution 2 - C

I don't believe there is. But what would you do with such a number if they are not sequential, and you don't already have a list of them somewhere? And if they are sequential but start at a different number, you could always do:

enum blah {
    FIRST = 128,
    SECOND,
    THIRD,
    END
};
const int blah_count = END - FIRST;

Solution 3 - C

Old question, I know. This is for the googlers with the same question.

You could use X-Macros

Example:

//The values are defined via a map which calls a given macro which is defined later
#define ENUM_MAP(X) \
      X(VALA, 0)    \
      X(VALB, 10)   \
      X(VALC, 20)

//Using the map for the enum decl
#define X(n, v) [n] = v,
typedef enum val_list {
    ENUM_MAP(X) //results in [VALA] = 0, etc...
} val_list;
#undef X

//For the count of values
#define X(n, v) + 1
int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1
#undef X

This is also transparent to an IDE, so auto-completes will work fine (as its all done in the pre-processor).

Solution 4 - C

Unfortunately, no. There is not.

Solution 5 - C

I know this is a very old question, but as the accepted answer is wrong, I feel compelled to post my own. I'll reuse the accepted answer's example, slightly modified. (Making the assumption that enums are sequential.)

// Incorrect code, do not use!
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST;
// And this above would be 3 - 0 = 3, although there actually are 4 items.

Any developer knows the reason: count = last - first + 1. And this works with any combination of signs (both ends negative, both positive, or only first end negative). You can try.

// Now, the correct version.
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST + 1; // 4

Edit: reading the text again, I got a doubt. Is that END meant not to be part of the offered items? That looks weird to me, but well, I guess it could make sense...

Solution 6 - C

Well, since enums can't change at run-time, the best thing you can do is:

enum blah {
    FIRST = 7,
    SECOND = 15,
    THIRD = 9,
    LAST = 12
};
#define blahcount 4 /* counted manually, keep these in sync */

But I find it difficult to envisage a situation where that information would come in handy. What exactly are you trying to do?

Solution 7 - C

int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};

#define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );

Solution 8 - C

#include <stdio.h>

// M_CONC and M_CONC_ come from https://stackoverflow.com/a/14804003/7067195
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B

#define enum_count_suffix _count
#define count(tag) M_CONC(tag, enum_count_suffix)
#define countable_enum(tag, ...) \
  enum tag {__VA_ARGS__}; \
  const size_t count(tag) = sizeof((int []) {__VA_ARGS__}) / sizeof(int)

// The following declares an enum with tag `color` and 3 constants: `red`,
// `green`, and `blue`.
countable_enum(color, red, green, blue);

int main(int argc, char **argv) {
  // The following prints 3, as expected.
  printf("number of elements in enum: %d\n", count(color));
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeter GibsonView Question on Stackoverflow
Solution 1 - CvpicaverView Answer on Stackoverflow
Solution 2 - CBrian CampbellView Answer on Stackoverflow
Solution 3 - CSamView Answer on Stackoverflow
Solution 4 - CrlbondView Answer on Stackoverflow
Solution 5 - CDavid StosikView Answer on Stackoverflow
Solution 6 - CpaxdiabloView Answer on Stackoverflow
Solution 7 - CiuoiView Answer on Stackoverflow
Solution 8 - CmathedpotatoesView Answer on Stackoverflow