# V721. The VARIANT_BOOL type is used incorrectly. The true value (VARIANT_TRUE) is defined as -1.

Анализатор обнаружил, что неправильно используется значение типа VARIANT_BOOL. Дело в том, что значение истина (VARIANT_TRUE) обозначается как -1. Многие программисты не ожидают такого подвоха и используют тип неправильно.

Вот как объявлен тип VARIANT_TRUE и константы для обозначения "истина" и "ложь":

    typedef short VARIANT_BOOL;
    #define VARIANT_TRUE ((VARIANT_BOOL)-1)
    #define VARIANT_FALSE ((VARIANT_BOOL)0)

Рассмотрим несколько примеров неправильной работы с типом VARIANT_TRUE. Во всех случаях программист ожидает, что условие будет истинно. Но на самом деле условие всегда ложно.

Пример N1.

    VARIANT_BOOL variantBoolTrue = VARIANT_TRUE;
    if (variantBoolTrue == true) // false

Если подставить значение в выражение, то мы получим: ((short)(-1) == true). При вычислении выражения, 'true' превратится в '1'. Условие (-1 == 1) ложно.

Правильный вариант:

    if (variantBoolTrue == VARIANT_TRUE)

Пример N2.

    VARIANT_BOOL variantBoolTrue = TRUE;
    if (variantBoolTrue == VARIANT_TRUE) //false

Здесь программист ошибся и использовал TRUE вместо VARIANT_TRUE. В результате переменной variantBoolTrue будет присвоено значение 1. Это недопустимое значение для переменных типа VARIANT_BOOL.

Если подставить значение в выражение, то мы получим: (1 == (short)(-1)).

Правильный вариант:

    VARIANT_BOOL variantBoolTrue = VARIANT_TRUE;

Пример N3.

    bool bTrue = true;
    if (bTrue == VARIANT_TRUE) //false

Раскроем выражение: (true == (short)(-1)). При вычислении выражения 'true' превратится в '1'. Условие (1 == -1) ложно.

Правильный вариант привести затруднительно. Код в принципе неверен. Нельзя смешивать переменные типа 'bool' и значения типа 'VARIANT_TRUE'.

Подобных примеров можно придумать достаточно много. Например, формальный аргумент функции имеет тип VARIANT_BOOL. А в качестве фактического аргумента будет передано значение 'true'. Ещё вариант - функция возвращает неправильно значение. И так далее.

Самое главное - не смешивать тип VARIANT_BOOL с типами BOOL, bool и BOOLEAN.

Дополнительные ссылки:

- MSDN. VARIANT_BOOL.
- The Old New Thing. BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. bool.

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

CWE-665 CWE-697 CERT-INT31-C

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