I'm trying to use enum in C to create a flags variable, as discussed here: Flags, enum (C)
How should I reset a single enum flag, when the compiler represents the enum as signed?
Problem:
Say I declare my flags type like this:
typedef enum {
FLAGS_A = 1 << 0,
FLAGS_B = 1 << 1,
FLAGS_C = 1 << 2,
FLAGS_D = 1 << 3
} flags_t;
flags_t flags;
I would like to reset a flag like this:
flags |= FLAGS_A; // Set A
flags &= (~FLAGS_A); // Reset A
However the compiler (Microchip XC8 Compiler V2.32) throws an error because bitwise operators should only be used on unsigned types. It looks like the enum is actually a signed integer under the hood.
Based on this question, it looks like there's no good way to force the compiler to use unsigned for enum: Is there a way to make an enum unsigned in the C90 standard? (MISRA-C 2004 compliant)
Things I've Tried:
One workaround I found was to add a special enumerated variable that has all the other flags set. I can use that as a mask to reset flag A:
typedef enum {
....
FLAGS_RESET_A = (FLAGS_B | FLAGS_C | FLAGS_D)
} flags_t
flag_t flags &= (FLAGS_RESET_A); // Reset A
This workaround is cumbersome. Any time I modify the flags type, such as adding a flag, I also have to remember to modify all the reset masks. I'm hoping there is a method that preserves the enum as a "single source of truth" for the flag definitions.
Another workaround is type casting to an unsigned integer, but that defeats the safety of using an enumerated type.