Open apolukhin opened 3 years ago
Antervis, 20 марта 2019, 12:54
В данном случае от аттрибута зависит поведение кода. Однако: All attributes unknown to an implementation are ignored without causing an error.(since C++17) Т.е. так сделать не получится. И соседнее предложение тоже не прокатит, по той же причине
Игорь Савенков, 20 марта 2019, 13:02 Antervis, Может тогда вообще вместо switch какое то другое ключевое слово завести? select? choise?
Игорь Савенков, 20 марта 2019, 13:05 Игорь Савенков, *choice
Удалённый пользователь, 20 марта 2019, 17:31
-Wswitch-enum GCC хорошо умеют это.
Visual studio C++ тоже есть такой варнинг.
Согласен с "удаленный пользователь" :)
Компиляторы давно умеют бросать warning на этот счёт, атрибут не нужен.
Перенос предложения: голоса +1, -2 Автор идеи: ??
Представим что есть такой код:
И вот что с ним не так:
1) Бесполезная ветка default. Если все работает как задумано, то эта ветка не должна выполняться вообще никогда.
2) Непонятки с самой последней инструкцией break; С виду она как-будто не нужна, но если ее удалить, а потом кто-то, например, из эстетических соображений перенесет default-ветку вверх switch-а то сразу возникнет ошибка из за пропавшего break. Вот код после этих 2х модификаций:
3) Если удалить default ветку а затем добавить только в enum дополнительное значение "three", то программа без проблем скомпилируется, хотя в switch не перебраны все варианты enum-a и нет default ветки. Что тоже выглядит не так как задумано. Пример такой модификации:
4) Так же этот код возможно сломать, если убрать инициализацию переменной значением TestEnum::one . Тогда в switch будет выполняться default ветка, что тоже не выглядит как хорошее поведение для неинициализированной переменной.
Предлагаю следующее:
1) Добавить в enum class атрибут, который бы существенно ограничивал возможности создания такого enum-а без значения, например [[strict]]
2) Добавить в switch атрибут, например [[strict]], который бы гарантировал перебор всех значений enum ов и убирал нерабочие ветки:
Чтобы это сделать, нужно во-первых сделать break-поведение, поведением по-умолчанию. Т.е. мы убираем все break операторы и подразумеваем что в конце всех case будет автоматом происходить выходить из switch. Во-вторых нужно гарантировать представленность всех случаев enum-а Если параметром [[strict]] switch передали обычный enum то выдавать compilation error
Если параметром в [[strict]] switch передали enum class (enum, который без атрибута [[strict]]) то проверять, что обязательно есть default ветка, и обязательно есть все возможые case для значений этого enum, иначе compilation error. default ветка как раз для случаев, когда этот enum class инициализирован мусором. Если же нужен [[strict]] switch не по всем значениям enum class, то можно например добавить атрибут [[notfull]], тогда все скомпилится. Важно! атрибут [[notfull]] нужен только в комбинации [[strict]] switch + enum class (не строгий)
Если параметром в [[strict]] switch передали enum class [[strict]], то должно быть всего 2 возможных сценария, которые корректно скомпилируются: либо в этом switch укзааны все возможные значения enum и отсутствует default ветка, либо пропущен один или несколько вариантов enum и тогда default ветка гарантированно присутствует, иначе ошибка компиляции. Примеры кода: