C++: how to check, that enum has only unique values
Asked Answered
E

2

3

we use VS 2008

there is a big enum, which is populated by many developers

this enum has a type __int64 (a Microsoft extension), and I want to make compiler complain about non unique values in enum.

if it was a usual enum I would do like this:

enum E1
{
    E11 = 0x01F00,
    E12 = 0x01F00,
    E13
};
#pragma warning(push)
#pragma warning(error: 4061)
#pragma warning(error: 4062)
void F(E1 e1)
{
    switch (e1)
    {
    case E11:
    case E12:
    case E13:
        return;
    }
}
#pragma warning(pop)

and the function F would have an error, if E1 has 2 same values

and it would have another error, if a developer forgot to add a new value to switch

but my enum has type __int64 (or long long)

and when I try do the same switch for E1 e1 it truncates values and complains on values, wich difference is either 0x100000000, or 0x200000000 ....

if I cast e1 to __int64, the compiler does not complain, if a developer forgets to add a new value to the switch (so the whole check function becomes useless)

the question: does someone know what I can do about it? or maybe VS 2008 (or C++) has another instrument to ensure enum : __int64 has only unique values?

Enciso answered 29/6, 2012 at 14:13 Comment(8)
The best I can think of is don't explicitly specify values (other than the first one).Doorn
@Mark Sometimes enums are useful because compiler warn you if some value was missed in a switch. On the other hand, the values by itself could be used for some other purposes (not only to distinguish cases).Exceedingly
@Mark, these values are flags (0x000..01, 0x00..02, 0x00..04 etc)Enciso
I think if you use a macro to create the enum you could specify a tuple of values, these can then be iterated over to define a template< size_t > free function definition parametrized with the enum with internal linkage. If a value is used twice it will violate ODR and you'll get a compilation error, if it works you get a ton of useless functions which hopefully your compiler will optimize away. It's very hacky but I think it would work in theory at least :PCelenacelene
Violating the ODR is not guaranteed to generate any sort of diagnostic.Doorn
I suppose writing a program that reads in your header file(s), parses out the enums, checks the enum values, and prints out error messages (and returns failure) if it finds duplicates, and adding that program to your build process is probably not what you had in mind, but if all else fails it would do the trick.Creaturely
C/C++ enums: Detect when multiple items map to same value, c++: ensure enum values are unique at compile time, C++11 Enum class containing duplicate valuesIsom
Does this answer your question? C/C++ enums: Detect when multiple items map to same valueIsom
D
2

From your comment I'll assume that you don't have aggregate (combined) flags within the enum itself. In that case you can use two enums to make it much harder to make mistakes. You can still subvert the compiler but I assume that's not the real problem here.

enum Bit_Index
{
    FLAG1_INDEX,
    FLAG2_INDEX,
    FLAG_FANCY_INDEX,
    LAST_INDEX
};

#define DECLARE_BIT_VALUE(att) att##_VALUE = 1ULL << att##_INDEX
enum Bit_Value
{
    DECLARE_BIT_VALUE(FLAG1),
    DECLARE_BIT_VALUE(FLAG2),
    DECLARE_BIT_VALUE(FLAG_FANCY),

    // Declared NOT using the macro so we can static assert that we didn't forget
    // to add new values to this enum.
    LAST_BIT   // Mainly a placeholder to prevent constantly having to add new commas with new ids.
};
#undef DECLARE_BIT_VALUE

Then in an implementation file you static_assert to make sure the enums don't get misaligned:

// Make sure to the best of our abilities that we didn't mismatch the index/bit enums.
BOOST_STATIC_ASSERT((LAST_BIT - 1) == (1U << (LAST_INDEX - 1)));
Doorn answered 29/6, 2012 at 14:47 Comment(1)
good idea. I can check the first enum with switch (and hope others will use the second enum in the same way). It's not a 100% guarantee, but much better, than nothing. Thanks.Enciso
M
0

Does someone know what I can do about it.

Other answer can be an algorithmic analysis. Static analysis is not necessarily a search for security vulnerabilities. Unfortunately in this case you will have to use an external tool for verification of your constraint. I can help you in implementing that.

Masturbation answered 29/6, 2012 at 22:32 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.