Cenum safety warning
Before relying on compiler warnings for enum mismatches, it’s important to know when or if such warnings will be generated.
We have a burrito ordering service.
typedef enum {
VEGGIE,
ONEMEAT,
MEGAMEAT,
} flavor_t;
typedef enum {
ASAP,
ONEHOUR,
TOMORROW,
} pickup_t;
void burrito(pickup_t, flavor_t);
We’re really hungry, so we want to order a megameat burrito for right freaking now.
burrito(MEGAMEAT, ASAP);
Unfortunately, in our hunger induced delirious rush, we’ve actually placed an order for a veggie burrito for tomorrow.
Preventable?
clang 8.0.1 does warning about this (twice). And without even asking for warnings. implicit conversion from enumeration type 'flavor_t' to different enumeration type
That’s good.
gcc 8.3.0 does not warn, even when using -W -Wall -Wextra
. Perhaps there’s another option, but that’s as far as I pushed it.
Unfortunately, it’s also fairly easy to circumvent clang’s warning as well with a touch of carelessness. I wasn’t able to illicit a warning for this code with -W -Wall -Wextra
with clang.
int f = MEGAMEAT;
int p = ASAP;
burrito(f, p);
I mean, don’t do that, but it’s not unheard of for programmers to take such shortcuts. Or for legacy code that started using int to be only partially converted to enum.
We often speak of compiler warnings and errors, although that’s not the language used in the C standard, which instead refers to diagnostic messages, which must be emitted for syntax errors and certain other constraint violations. Many common mistakes (including any number of undefined behaviors) are not technically constraint violations, and thus there is no requirement for the compiler to diagnose them. For the most consistent results between compilers, relying on contraint violations to catch mistakes works better.
Mostly. I personally dislike reversed conditionals of the form if (0 == x)
because they’re hard to read. Fortunately, pretty much every compiler will warn about unintentional assignments, so that’s a case where I feel safe relying on the compiler to catch my mistakes, even if if (x = 0)
is permitted by the language.