Here's a simple code-pattern that keeps biting me in our codebase:
// in some_header_file.h
enum Color {
red = 0,
green,
blue,
max_item
};
// in some_other_file.cpp
static const char * color_names[max_item] = {
"red",
"green",
"blue"
};
std::string get_color_name(Color c) {
if ((c >= 0) && (c < max_item)) return color_names[c];
return "Unknown color";
}
... the above is all well and good, until one day, some careless programmer (okay, it's usually me) comes by and inserts a new color (e.g. yellow) into the Colors enum in some_header_file.h (just before max_item), but forgets to also add the new color's string (e.g. "yellow") to the end of the color_names[max_item] array in some_other_file.cpp.
After that happens, the code compiles fine with no errors or warnings, but future calls to get_color_name(yellow) will (at best) not return the expected result or (at worst) invoke undefined behavior and maybe crash.
What I'd like is for this mistake to be caught at compile-time, so that I can avoid introducing runtime-error when updating enums. Is there a way in C++ to enforce at compile-time that the number of initializer-strings for color_names must be equal to the array's length (i.e. to max_item)?

The easiest would probably be to remove
max_itemfrom the array size and let it be automatically sized and thenstatic_asserton the size: