Я бы поставил assert
.
Special make_special( Enum e )
{
switch( e )
{
case Enum_One:
return Special( /*stuff one*/ );
case Enum_Two:
return Special( /*stuff two*/ );
default:
assert(0 && "Unhandled special enum constant!");
}
}
Отсутствие обработки значения перечисления, хотя цель состоит в том, чтобы охватить все случаи, является ошибкой в коде, которую необходимо исправить. Ошибка не может быть решена и не обработана "изящно", и должна быть исправлена сразу (чтобы я не бросал). Чтобы компилятор молчал о предупреждениях «не возвращать значения», вызовите abort
, например,
#ifndef NDEBUG
#define unreachable(MSG) \
(assert(0 && MSG), abort())
#else
#define unreachable(MSG) \
(std::fprintf(stderr, "UNREACHABLE executed at %s:%d\n", \
__FILE__, __LINE__), abort())
#endif
Special make_special( Enum e )
{
switch( e )
{
case Enum_One:
return Special( /*stuff one*/ );
case Enum_Two:
return Special( /*stuff two*/ );
default:
unreachable("Unhandled special enum constant!");
}
}
Компилятор больше не предупреждает о возврате без значения, поскольку он знает, что abort
никогда не вернется. Мы немедленно завершаем работу программы, в которой произошел сбой, что, на мой взгляд, является единственной разумной реакцией (нет смысла продолжать запускать программу, которая вызвала неопределенное поведение).