C++: как проверить, что enum имеет только уникальные значения

Мы используем VS 2008

есть большое перечисление, которое заполняется многими разработчиками

этот enum имеет тип __int64 (расширение Microsoft), и я хочу, чтобы компилятор жаловался на неуникальные значения в enum.

если бы это был обычный enum, я бы сделал так:

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)

и функция F будет иметь ошибку, если E1 имеет 2 одинаковых значения

и это будет иметь другую ошибку, если разработчик забыл добавить новое значение для переключения

но мой enum имеет тип __int64 (или long long)

и когда я пытаюсь сделать тот же переключатель для E1 e1, он усекает значения и жалуется на значения, разница которых составляет либо 0x100000000, либо 0x200000000 ....

если я приведу e1 к __int64, компилятор не будет жаловаться, если разработчик забудет добавить новое значение в переключатель (так что вся функция проверки становится бесполезной)

вопрос: кто-то знает, что я могу с этим сделать? или, может быть, VS 2008 (или C++) имеет другой инструмент для обеспечения перечисления: __int64 имеет только уникальные значения?

2 ответа

Решение

Из вашего комментария я предполагаю, что у вас нет агрегатных (комбинированных) флагов внутри самого перечисления. В этом случае вы можете использовать два перечисления, чтобы сделать ошибки намного сложнее. Вы все еще можете подорвать компилятор, но я предполагаю, что это не настоящая проблема здесь.

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

Затем в файле реализации вы используете static_assert, чтобы убедиться, что перечисления не выровнены:

// 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)));

Кто-нибудь знает, что я могу с этим поделать.

Другим ответом может быть алгоритмический анализ. Статический анализ не обязательно является поиском уязвимостей безопасности. К сожалению, в этом случае вам придется использовать внешний инструмент для проверки вашего ограничения. Я могу помочь вам в реализации этого.

Другие вопросы по тегам