﻿# V560\. Part of conditional expression is always true/false\.

Анализатор обнаружил потенциально возможную ошибку внутри логического условия\. Часть логического выражения всегда истинно и оценено как опасное\.

Рассмотрим пример:

```cpp
#define REO_INPLACEACTIVE (0x02000000L)
...
if (reObj.dwFlags && REO_INPLACEACTIVE)
  m_pRichEditOle->InPlaceDeactivate();
```

Программист хотел проверить состояние определенного бита в переменной dwFlags\. Но из\-за опечатки он написал оператор '&&', вместо оператора '&'\. Корректный код:

```cpp
if (reObj.dwFlags & REO_INPLACEACTIVE)
  m_pRichEditOle->InPlaceDeactivate();
```

Рассмотрим другой пример:

```cpp
if (a = 10 || a == 20)
```

Случайно вместо оператора сравнения '\=\=' написан оператор присваивания '\='\. С точки зрения языка Си\+\+, это выражение будет идентично выражению вида "if \(a \= \(10 \|\| a \=\= 20\)\)"\.

Выражение "10 \|\| a \=\= 20" анализатор считает опасным, так как левая его часть представляет собой константу\. Корректный код:

```cpp
if (a == 10 || a == 20)
```

Иногда предупреждение V560 выявляет не ошибку, а просто избыточный код\. Рассмотрим пример:

```cpp
if (!mainmenu) {
  if (freeze || winfreeze ||
      (mainmenu && gameon) ||
      (!gameon && gamestarted))
    drawmode = normalmode;
}
```

Анализатор предупредит, что в подвыражении \(mainmenu && gameon\) переменная mainmenu всегда равна 0\. То, что переменная mainmenu  равна нулю, следует из вышестоящей проверки " if \(\!mainmenu\)"\. Этот код может быть вполне корректен\. Однако он избыточен, и лучше его упростить\. Это сделает программу более простой для понимания другими разработчиками\. 

Упрощенный вариант кода:

```cpp
if (!mainmenu) {
  if (freeze || winfreeze ||
      (!gameon && gamestarted))
    drawmode = normalmode;
}
```

Рассмотрим более интересный случай\.

```cpp
int16u Integer = ReadInt16u(Liste);
int32u Exponent=(Integer>>10) & 0xFF;
if (Exponent==0 || Exponent==0xFF)  // V560
  return 0;
```

Пользователь, приславший этот пример, был озадачен, почему анализатор выдаёт предупреждение, в котором утверждается, что подвыражение 'Exponent\=\=0xFF' всегда ложное\. Давайте разберемся\. Для этого нам надо внимательно посчитать\.

16\-битная беззнаковая переменная 'Integer' имеет диапазон возможных значений \[0\.\.0b1111111111111111\] или \[0\.\.0xFFFF\]\.

При сдвиге вправо на 10 бит, диапазон возможных значений уменьшается: \[0\.\.0b111111\] или \[0\.\.0x3F\]\.

Далее выполняется операция '& 0xFF'\.

В результате, никак невозможно получить значение '0xFF'\. Максимум, это будет '0x3F'\.

Ряд конструкций на языке Си\+\+ анализатор считает безопасными, даже если в них часть выражения представляется константой\. Примеры некоторых ситуаций, когда анализатор не считает код опасными:

* подвыражение содержит операторы sizeof\(\): if \(a \=\= b && sizeof\(T\) < sizeof\(\_\_int64\)\) \{\};
* выражение находится в макросе: assert\(false\);
* сравниваются две числовых константы: if \(MY\_DEFINE\_BITS\_COUNT \=\= 4\) \{\};
* и так далее\.

**Особые настройки диагностики V560**

По дополнительной просьбе пользователей появилась возможность управлять поведением диагностики V560\. В общем заголовочном файле или pvsconfig\-файле можно написать комментарий специального вида:

```cpp
//+V560 ENABLE_PEDANTIC_WARNINGS
```

Режим 'ENABLE\_PEDANTIC\_WARNINGS' ослабляет исключения диагностики\. Рассмотрим пример:

```cpp
void foo()
{
  bool debugCheck = false; // maybe in macros
  if (x)
  {
    if (debugCheck)
    {
      ....
    }
  }
}
```

По умолчанию анализатор не будет считать такой код опасным, так как часто он пишется для отладки\. Комментарий позволит ослабить исключение диагностики, чтобы анализатор мог сообщить о проблеме\.