In C how to loop for each enumerated literal where the literals do't have consecutive values

StackOverflow https://stackoverflow.com/questions/20993142

  •  25-09-2022
  •  | 
  •  

Question

Suppose i have the following enumerated literal

enum
{
valueA = 5,
valueB = 7,
valueC = 9,
valueD = 14,
valueE = 15
}myEnumType; 

and i want to loop through each literal eg

for (enumType myValEnum = valueA; myValEnum <= valueE; myValEnum++)
{
    MyFunction(mValEnum);
}

will that work or will I end up calling MyFunction with values 5,6,7,8,9,10,11,12,13,14,15 ?

Was it helpful?

Solution

You can't do that, there's no support for a "foreach" type of iteration over the enumeration in C. Basically, enumerations are just aliased integers, with little extra support.

You need to use a mapping table, that allows you to map consecutive indices to values of the enumerated type:

static const myEnumType myEnumMap[] = { valueA, valueB, valueC, valueD, valueE};

then you can use a plain loop over that array:

for(size_t i = 0; i < sizeof myEnumMap / sizeof *myEnumMap; ++i)
{
  const myEnumType ie = myEnumMap[i];
  /* process ie */
}

Note that the type of myEnumMap is the type of your enumeration, it's not a plain "array of integers".

This has the downside of requiring the enum to be enumerated twice (once in its own definition, then again in the myEnumMap initializer). It's possible to work around that using macro trickery (such as X macros), but there's no real convenient/easy way to do it.

OTHER TIPS

Directly it is not possible to loop through each enum literal. You can do that indirectly by using an array of integers. Assign each enum literals to array elements sequentially and then you can loop through each array element.

I am not sure, if this is helpful, but I had the following thoughts:

We have to save the possible values of the enum somewhere, because this information doesn't exist in memory, so we need something like an array with the possible values:

enum {
    valueA = 5,
    valueB = 7,
    valueC = 9,
    valueD = 14,
    valueE = 15
} myEnumType;

const int myEnumTypeArr[] = { 5, 7, 9, 14, 15 };

where it's possible to not store that array but to create a temporary object whenever needed (e.g. we could wrap the array contents into a macro).

I don't think that's a good solution, though, because if you change your enum, you must change the array. If you forget to do so, the compiler won't warn you and it may result in hard-to-find bugs.

So maybe the following is helpful: You use the array for the values and the enum constants as indexes:

enum { valueA, valueB, valueC, dummy } myEnumType; // dummy must stay at last position
const int myEnumTypeArr[] = { 5, 7, 9 };

so you use myEnumTypeArr[valueA] rather than valueA directly (with the drawback, that it's no longer a constant, e.g. can't be used as a case label) and maybe something like that (somewhat ugly, though)

static_assert( sizeof myEnumTypeArr / sizeof *myEnumTypeArr == dummy );

to prevent the aforementioned bug.

HTH

You can't do it using enum and loops. Your loop

for (enumType myValEnum = valueA; myValEnum <= valueE; myValEnum++)
{
    MyFunction(mValEnum);
}

iterates from 5 to 15(5,6,7,8,9,10,11,12,13,14,15). According to my knowledge pointer to enum's also can't help you here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top