Is there a compile-time way to detect / prevent duplicate values within a C/C++ enumeration?
The catch is that there are multiple items which are initialized to explicit values.
Background:
I’ve inherited some C code such as the following:
#define BASE1_VAL (5)
#define BASE2_VAL (7)
typedef enum
{
MsgFoo1A = BASE1_VAL, // 5
MsgFoo1B, // 6
MsgFoo1C, // 7
MsgFoo1D, // 8
MsgFoo1E, // 9
MsgFoo2A = BASE2_VAL, // Uh oh! 7 again...
MsgFoo2B // Uh oh! 8 again...
} FOO;
The problem is that as the code grows & as developers add more messages to the MsgFoo1x group, eventually it overruns BASE2_VAL.
This code will eventually be migrated to C++, so if there is a C++-only solution (template magic?), that’s OK — but a solution that works with C and C++ is better.
There are a couple ways to check this compile time, but they might not always work for you. Start by inserting a “marker” enum value right before MsgFoo2A.
Now we need a way to ensure that
MARKER_1_DONT_USE < BASE2_VALat compile-time. There are two common techiques.Negative size arrays
It is an error to declare an array with negative size. This looks a little ugly, but it works.
Almost every compiler ever written will generate an error if MARKER_1_DONT_USE is greater than BASE_2_VAL. GCC spits out:
Static assertions
If your compiler supports C11, you can use
_Static_assert. Support for C11 is not ubiquitous, but your compiler may support_Static_assertanyway, especially since the corresponding feature in C++ is widely supported.GCC spits out the following message: