To get a trial key
fill out the form below
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement

Request our prices
New License
License Renewal
--Select currency--
USD
EUR
RUB
* By clicking this button you agree to our Privacy Policy statement

Free PVS-Studio license for Microsoft MVP specialists
** By clicking this button you agree to our Privacy Policy statement

To get the licence for your open-source project, please fill out this form
** By clicking this button you agree to our Privacy Policy statement

I am interested to try it on the platforms:
** By clicking this button you agree to our Privacy Policy statement

Message submitted.

Your message has been sent. We will email you at


If you haven't received our response, please do the following:
check your Spam/Junk folder and click the "Not Spam" button for our message.
This way, you won't miss messages from our team in the future.

>
>
>
V1087. Upper bound of case range is les…
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Diagnosis of micro-optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
Contents

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

Aug 05 2022

The analyzer detected a situation where the upper bound of range in the 'case' label is less than its lower bound. Perhaps, this is a typo, and the part of code may become unreachable.

The GCC and Clang compilers have the Case Ranges extension which allows you to specify a range of constant values instead of a single value for the 'case' label. Such a range will be similar to the sequence of 'case' labels, including boundary values:

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

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

However, if the upper bound of the specified range is less than its lower bound, this range will be treated as empty. If you specify such a range, then during the condition check control can never be passed to the label. Therefore, the code branch can become unreachable.

Look at the synthetic example:

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

In the second label, the '4' and '6' constants were mixed up in places, which is why control will never be transferred to the label. Correct example:

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

An error of this kind can occur when named constants or values returned by 'constexpr' functions are incorrectly used. Look at the synthetic example:

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;
  }
}

There's a typo in the second label. Because of this, function calls are mixed up in places, and control will never be passed to the label. Correct example:

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;
  }
}

However, incorrect range doesn't always lead to unreachable code. If there is no 'break' in the 'case' label above, then after its branch is executed, control will be passed to 'case' with an empty range. Synthetic example:

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
  }
}

Despite the code is reachable, an empty range looks strange and meaningless. This may be a typo or incorrect macro expansion. Therefore, the absence of 'break' in the label above is not an exception for the diagnostic, and the analyzer will issue a warning.

This diagnostic is classified as:

Unicorn with delicious cookie
Our website uses cookies to enhance your browsing experience.
Accept