cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
91 stars 0 forks source link

Добавить атрибут для default метки, который будет выдавать warning если не все значения enum обработаны в switch #554

Open adromanov opened 1 year ago

adromanov commented 1 year ago

Предложение добавить атрибут для default метки, который будет выдавать warning если не все значения enum обработаны в switch. Конкретное имя для аттрибута - to be discussed, для примера назовём его [[enum-switch]] по аналогии с флагом gcc \ clang -Wenum-switch

enum class Enum { A, B, C };
const Enum value = get_value();
switch (value)
{
case Enum::A: return "A";
case Enum::B: return "B";
case Enum::C: return "C";
[[enum-switch]] default: return "Unknown";
};

Использования метки default в switch по значению enum в данный момент можно разделить на 2 категории: 1) Мы явно указываем несколько, но не все значения enum, которые хотим обработать, а также хотим иметь логику по умолчанию для всех остальных значений. 2) Мы имеем метки для всех возможных значений enum, но имеем метку default на случай, если что-то пошло не так. Например, мы обрабатываем сообщение от третьей стороны и делаем switch по типу сообщения. В большинстве случаев нам будут приходить только те сообщения, которые описаны в протоколе, но в общем случае мы не можем на 100% доверять данным, приходящим извне - невалидные данные могут быть присланы со злым умыслом или повреждены во время передачи.

Для второй категории новый атрибут будет полезен - при добавлении нового значения в enum компилятор предупредит нас о том, что новое значение не обработано в switch даже если есть default метка - так же, как сейчас компиляторы с флагом -Wenum-switch предупреждают, если нет метки default и не все значения enum имеют метки.

Этого нельзя добиться дополнительным флагом для компилятора потому что есть случаи, когда мы сознательно не перечисляем остальные значения enum (категория 1).

Желаемого поведения можно добиться, вынеся код из default за пределы switch, но в некоторых случаях это усложнит код - например, мы хотим сделать ранний возврат из default метки. Поэтому я считаю, что с новым аттрибутом код будет проще и менее подвержен ошибкам.