Анализатор обнаружил подозрительный оператор switch. Выбор варианта осуществляется по переменной enum-типа. При этом рассмотрены не все возможные варианты.
Пример:
enum TEnum { A, B, C, D, E, F };
....
TEnum x = foo();
switch (x)
{
case A: Y(11); break;
case B: Y(22); break;
case C: Y(33); break;
case D: Y(44); break;
case E: Y(55); break;
}
Перечисление TEnum содержит 6 именованных констант. Но в операторе switch используется только 5 из них. Высока вероятность, что это ошибка.
Такая проблема часто возникает в ходе рефакторинга. В TEnum добавили константу F. После этого какие-то switch поправили, а про какие-то забыли. В результате значение F начинает обрабатываться неправильно.
Анализатор предупредит о том, что константа F не используется. И тогда программист может исправить ошибку:
switch (x)
{
case A: Y(11); break;
case B: Y(22); break;
case C: Y(33); break;
case D: Y(44); break;
case E: Y(55); break;
case F: Y(66); break;
}
Анализатор выдаёт предупреждение далеко не всегда, когда в switch используется не все константы из перечисления. Иначе было бы слишком много ложных срабатываний. По умолчанию действует целый ряд исключений эмпирического типа. Основные:
switch не используется более чем 4 константы;switch не используется половина и более элементов;None, Unknown и т.п.end, num, count и т. п.Описанные исключения являются взвешенным решением, проверенным на практике. Если вам нужно другое поведение, его можно изменить с помощью настроек, описанных в следующем разделе.
Для изменения поведения диагностического правила добавьте в файл .pvsconfig одну или несколько следующих команд.
По умолчанию анализатор не выдаёт предупреждения о неиспользуемых значениях enum при наличии default ветки. Это решение связано с большим количеством потенциально ложных срабатываний в случаях, когда в default-ветке находится assert или бросок исключения.
Пример:
enum TEnum { A, B, C, D, E, F };
....
TEnum x = foo();
switch (x)
{
case A: Y(11); break;
case B: Y(22); break;
case C: Y(33); break;
case D: Y(44); break;
case E: Y(55); break;
default:
throw MyException("Ай! Забыли рассмотреть один из вариантов!");
}
Тем не менее, если вам необходимо искать все неиспользуемые значения, невзирая на наличие default-ветки, то вы можете воспользоваться следующей настройкой:
`//+V719 IGNORE_DEFAULT:ON` (по умолчанию)
`//+V719 IGNORE_DEFAULT:OFF`
По умолчанию анализатор не выдаёт предупреждение, если неиспользуемый элемент находится в enum, который состоит всего из одного или двух элементов. Изменить это поведение можно с помощью следующей настройки:
`//+V719 IGNORE_SMALL_ENUM:ON` (по умолчанию)
`//+V719 IGNORE_SMALL_ENUM:OFF`
По умолчанию анализатор не будет выдавать предупреждение на отсутствующий элемент, если он находится последним в enum и содержит в названии подстроки end, num, count, max, last и т.п.
Если необходимо, вы можете определить свой список имен с помощью следующей настройки:
`//-V719_COUNT_NAME:NAME1, *END,LAST?ELEMENT*`
Примечания:
* (ноль и более любых символов);? (один любой символ). * и ?), то будет искаться подстрока.По умолчанию анализатор перестанет выдавать предупреждение, если в switchпропущено более четырёх констант. Изменить это количество можно с помощью настройки:
//+V719 MAX_UNCOVERED_ENUMERATORS: 2
Чтобы полностью убрать это ограничение, задайте значение, равное нулю:
//+V719 MAX_UNCOVERED_ENUMERATORS: 0
С помощью указанной ниже настройки вы можете задать имена констант, пропуск которых анализатор не будет считать ошибкой:
//-V719_IGNORE_ENUMERATORS: WithN?, *_DONT_USE, ExactName
Примечания:
* (ноль и более любых символов);? (один любой символ). Диагностическое правило классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V719. |