Detect when multiple enum items map to same value

后端 未结 8 2156
猫巷女王i
猫巷女王i 2020-11-28 13:44

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 initialize

8条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-11-28 13:50

    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.

    typedef enum
    {
        MsgFoo1A = BASE1_VAL,
        MsgFoo1B,
        MsgFoo1C,
        MsgFoo1D,
        MsgFoo1E,
        MARKER_1_DONT_USE, /* Don't use this value, but leave it here.  */
        MsgFoo2A = BASE2_VAL,
        MsgFoo2B
    } FOO;
    

    Now we need a way to ensure that MARKER_1_DONT_USE < BASE2_VAL at 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.

    extern int IGNORE_ENUM_CHECK[MARKER_1_DONT_USE > BASE2_VAL ? -1 : 1];
    

    Almost every compiler ever written will generate an error if MARKER_1_DONT_USE is greater than BASE_2_VAL. GCC spits out:

    test.c:16: error: size of array ‘IGNORE_ENUM_CHECK’ is negative
    

    Static assertions

    If your compiler supports C11, you can use _Static_assert. Support for C11 is not ubiquitous, but your compiler may support _Static_assert anyway, especially since the corresponding feature in C++ is widely supported.

    _Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");
    

    GCC spits out the following message:

    test.c:16:1: error: static assertion failed: "Enum values overlap."
     _Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");
     ^
    

提交回复
热议问题