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)));
Кто-нибудь знает, что я могу с этим поделать.
Другим ответом может быть алгоритмический анализ. Статический анализ не обязательно является поиском уязвимостей безопасности. К сожалению, в этом случае вам придется использовать внешний инструмент для проверки вашего ограничения. Я могу помочь вам в реализации этого.