V676. It is incorrect to compare the variable of BOOL type with TRUE.


Анализатор обнаружил, что значение типа BOOL сравнивается с константой TRUE (или 1). Это является потенциальной ошибкой, так как значение "истина" может быть любым числом, отличным от нуля.

Для начала вспомним, в чем отличие типа 'bool' и 'BOOL'.

Конструкция вида:

bool x = ....;
if (x == true) ....

совершенно корректна. Тип 'bool' может принимать только два значения: true и false.

В случае с типом BOOL такие проверки недопустимы. Тип BOOL представляет на самом деле тип 'int'. Это значит, что он может хранить значения, отличные от нуля и единицы. Любое значение, отличное от нуля считается "истинным".

Отличные от 1 значения могут возвращаться, например, функциями из Windows SDK.

Константы FALSE/TRUE объявлены следующим образом:

#define FALSE               0
#define TRUE                1

Это значит, что следующее сравнение может дать сбой:

BOOL ret = Some_SDK_Function();
if (TRUE == ret)
{
  // do something
}

Нет гарантии, что функция Some_SDK_Function() вернет именно единицу, если будет успешно выполнена. Правильно будет написать:

if (FALSE != ret)

Или:

if (ret)

По данной тематике также можно порекомендовать познакомиться с FAQ на сайте CodeGuru: Visual C++ General: What is the difference between 'BOOL' and 'bool'?

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

if (CDialog::OnInitDialog() != TRUE )
  return FALSE;

В описании функции CDialog::OnInitDialog() сказано: "If OnInitDialog returns nonzero, Windows sets the input focus to the default location, the first control in the dialog box. The application can return 0 only if it has explicitly set the input focus to one of the controls in the dialog box."

Обратите внимание, нигде не сказано про TRUE или про 1. Правильный код:

if (CDialog::OnInitDialog() == FALSE)
  return FALSE;

Этот код может долго и успешно работать, но нет никакой гарантии, что так будет всегда.

Относительно ложных срабатываний. Иногда, программист точно знает, что переменная типа BOOL всегда будет иметь значение 0 или 1. В этом случае, можно подавить ложное срабатывание, одним из нескольких методов. Однако, намного лучше все-таки поправить код. Код станет более надежен по отношению к будущим рефакторингам.

Близкой по смыслу к этой диагностике является V642.

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-253.

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


Найденные ошибки

Проверено проектов
364
Собрано ошибок
13 504

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;