Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V719. The switch statement does not cover all values of the enum.

05 Мар 2015

Анализатор обнаружил подозрительный оператор 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 используется не все константы из перечисления. Иначе было бы слишком много ложных срабатываний. По умолчанию действует целый ряд исключений эмпирического типа. Основные:

  • есть default-ветка;
  • в перечислении всего 1 или 2 константы;
  • в switch не используется более чем 4 константы;
  • в switch не используется половина и более элементов;
  • отсутствующая константа содержит в имени: None, Unknown и т.п.
  • отсутствующая константа самая последняя в enum и содержит в имени end, num, count и т. п.

Описанные исключения являются взвешенным решением, проверенным на практике. Если вам нужно другое поведение, его можно изменить с помощью настроек, описанных в следующем разделе.

Дополнительная настройка диагностического правила

Для изменения поведения диагностического правила добавьте в файл .pvsconfig одну или несколько следующих команд.

Исключение на наличие default-ветки

По умолчанию анализатор не выдаёт предупреждения о неиспользуемых значениях 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 (1-2 элемента)

По умолчанию анализатор не выдаёт предупреждение, если неиспользуемый элемент находится в 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

Примечания:

  • В качестве значения настройки можно передать паттерн, использующий спецсимволы:
  • * (ноль и более любых символов);
  • ? (один любой символ).
  • Несколько паттернов можно перечислить через запятую.
  • Если в паттерне не используются спецсимволы, будет искаться полное совпадение названия элемента перечисления.

Диагностическое правило классифицируется как:

  • CERT-MSC01-C

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V719.