How to iterate an enum?

Thread Starter

AlbertHall

Joined Jun 4, 2014
12,347
I don't think that is possible in standard C (PIC & XC8).
I was trying to use an enum so that any out of range item would generate a compile time error but in another part of the program I want to be able to iterate through through all the values in the enum so I can't do that. I could put the values in a constant array which would be easy to iterate but then using an incorrect value would not generate a compile time error.

Is there some way of achieving both requirements?
 

nsaspook

Joined Aug 27, 2009
13,315
Not sure what you want to do but adding a extra label at the end gives you the range of enum values. (if they are sequential from zero)
Software timer example:
https://raw.githubusercontent.com/nsaspook/vtouch_v2/mbmc/touch_v2.X/timers.h
C:
ifndef TIMERS_H
#define TIMERS_H

#include <stdint.h>
#include <stdbool.h>

//Software timers - use these to refer to timers rather than
//integers.  Add more as needed.
//NOTE: 32767 ms max delay

enum APP_TIMERS {
    TMR_INTERNAL = 0, //Used in timers.c - do not remove or use elsewhere
    TMR_ADC,
    TMR_T2,
    TMR_T3,
    TMR_T4,
    TMR_MC_TX,
    TMR_HBIO,
    TMR_INFO,
    TMR_HELP,
    TMR_HELPDIS,
    TMR_DISPLAY,
    TMR_FLIPPER,
    TMR_ESR,
    //
    //(Add timers here as needed)
    //
    TMR_COUNT //number of timers - always keep at end of enum!
};

void StartTimer(const uint8_t timer, const uint16_t count);
bool TimerDone(const uint8_t timer);
void WaitMs(const uint16_t numMilliseconds);

#endif //TIMERS_H
https://raw.githubusercontent.com/nsaspook/vtouch_v2/mbmc/touch_v2.X/timers.c
https://github.com/nsaspook/vtouch_v2/blob/mbmc/touch_v2.X/mcc_generated_files/tmr6.c
C:
void TMR6_DefaultInterruptHandler(void)
{
    uint8_t i;
    // add your TMR6 interrupt custom code
    // or set custom function using TMR6_SetInterruptHandler()

    //Decrement each software timer
    for (i = 0; i < TMR_COUNT; i++) {
        if (tickCount[i] != 0) {
            tickCount[i]--;
}
    }
}
 

Thread Starter

AlbertHall

Joined Jun 4, 2014
12,347
Nice!
But the values may not be consecutive.
I have an idea to use an array but then when a function is passed a value which is not one of the values in the array the function would search for the nearest value and use that.
 

ErnieM

Joined Apr 24, 2011
8,377
It cannot be done with a simple enum. C enums are just a list of identifiers, basically just a list of integer constant defines useful at compile time. The list is gone at run time.

Several recent languages such as Java, C#, Python (VB?) and the like have enumeration objects with multiple data items and methods so constructs such as "for each X in Y" will work, and work nicely too. This was not the intent of C.
 

nsaspook

Joined Aug 27, 2009
13,315
Nice!
But the values may not be consecutive.
I have an idea to use an array but then when a function is passed a value which is not one of the values in the array the function would search for the nearest value and use that.
In that case a level of indirection with range validation in a lookup table (array) might be useful. Consecutive enums as the key to the actual values in a array.
 
Top