Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V1087. Upper bound of case range is les…
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
Оглавление

V1087. Upper bound of case range is less than its lower bound. This case may be unreachable.

05 Авг 2022

Анализатор обнаружил ситуацию, когда верхняя граница диапазона в метке 'case' меньше, чем его нижняя граница. Возможно, это опечатка, из-за которой часть кода может быть недостижима.

В компиляторах GCC и Clang существует расширение Case Ranges, которое позволяет вместо единственного значения метки 'case' указать диапазон константных значений. Такой диапазон будет аналогичен последовательности меток 'case', включая граничные значения:

switch (....)
{
case 1 ... 3:
  // Do something
  break;
}

// Similar to the previous 'switch' statement
switch (....)
{
case 1:
case 2:
case 3:
  // Do something
  break;
}

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

Рассмотрим синтетический пример:

void foo(int i)
{
  switch (i)
  {
  case 1 ... 3:
    // First case
    break;
  case 6 ... 4:    // <=
    // Second case
    break;
  case 7 ... 9:
    // Third case
    break;
  }
}

Здесь во второй метке были перепутаны местами константы '4' и '6', из-за чего управление никогда не будет передано метке. Исправленный пример:

void foo(int i)
{
  switch (i)
  {
  case 1 ... 3:
    // First case
    break;
  case 4 ... 6:    // <=
    // Second case
    break;
  case 7 ... 9:
    // Third case
    break;
  }
}

Ошибка такого рода может возникнуть при неверном использовании именованных констант или значений, возвращаемых 'constexpr'-функциями. Рассмотрим синтетический пример:

constexpr int for_yourself_min() noexcept { return 1; }
constexpr int for_yourself_max() noexcept { return 3; }
constexpr int for_neighbors_min() noexcept { return 4; }
constexpr int for_neighbors_max() noexcept { return 6; }

void distributeCats(int count)
{
  switch (count)
  {
  case for_yourself_min() ... for_yourself_max():
    // Keep for yourself
    break;
  case for_neighbors_max() ... for_neighbors_min():      // <=
    // Give cats to neighbors
    break;
  default:
    // Give cats to a cattery
    break;
  }
}

Во второй метке из-за опечатки вызовы функций были перепутаны местами, и управление никогда не будет передано метке. Исправленный пример:

constexpr int for_yourself_min() noexcept { return 1; }
constexpr int for_yourself_max() noexcept { return 3; }
constexpr int for_neighbors_min() noexcept { return 4; }
constexpr int for_neighbors_max() noexcept { return 6; }

void distributeCats(int count)
{
  switch (count)
  {
  case for_yourself_min() ... for_yourself_max():
    // Keep for yourself
    break;
  case for_neighbors_min() ... for_neighbors_max():      // <=
    // Give cats to neighbors
    break;
  default:
    // Give cats to a cattery
    break;
  }
}

Однако неправильный диапазон не всегда ведет к недостижимому коду. Если в метке 'case' выше отсутствует 'break', то после выполнения его ветки управление будет передано в 'case' с пустым диапазоном. Синтетический пример:

void foo(int i)
{
  switch (i)
  {
  case 0: // no break
  case 3 ... 1:
    // First and second case
    break;
  case 4:
    // Third case
  default:
    // Do something
  }
}

Несмотря на достижимость кода, пустой диапазон выглядит странно и бессмысленно. Это может быть опечатка или неправильное раскрытие макросов. Поэтому отсутствие 'break' в метке выше не является исключением для диагностики, а предупреждение будет выдано.

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

Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо