﻿# В очередной раз анализатор PVS\-Studio оказался внимательнее человека

Изучая предупреждения анализатора PVS\-Studio в процессе проверки различных открытых проектов, мы вновь и вновь убеждаемся, сколь полезен может быть этот инструмент\. Анализатор кода невероятно внимателен и никогда не устаёт\. Он указывает на ошибки, которые ускользают даже при внимательном обзоре кода\. Рассмотрим очередной такой случай\.

![0582_Once_again_the_PVS_Studio_analyzer_has_proved_to_be_more_attentive_than_a_person_ru/image2.png](https://import.viva64.com/docx/blog/0582_Once_again_the_PVS_Studio_analyzer_has_proved_to_be_more_attentive_than_a_person_ru/image2.png)

В предыдущий раз я написал [аналогичную заметку](https://pvs-studio.ru/ru/blog/posts/cpp/0535/), изучая исходный код проекта StarEngine: 2D Game Engine\. Теперь анализатор показал своё превосходство надо мной в ходе проверки фреймворка Qt\.

Последний раз мы [проверяли](https://pvs-studio.ru/ru/blog/posts/cpp/0251/) фреймворк Qt в 2014 году\. Прошло много времени, проект изменился, а в анализаторе PVS\-Studio появилось много новых диагностик\. Значит, вполне можно написать очередную статью, чем я и занялся\.

Выписывая интересные примеры ошибок, я повстречал вот такой код:

```cpp
QWindowsCursor::CursorState QWindowsCursor::cursorState()
{
  enum { cursorShowing = 0x1, cursorSuppressed = 0x2 };
  CURSORINFO cursorInfo;
  cursorInfo.cbSize = sizeof(CURSORINFO);
  if (GetCursorInfo(&cursorInfo)) {
    if (cursorInfo.flags & CursorShowing)   // <= V616
  ....
}
```

Для этого кода PVS\-Studio выдал предупреждение:

V616 CWE\-480 The 'CursorShowing' named constant with the value of 0 is used in the bitwise operation\. qwindowscursor\.cpp 669

Для проверки использовалась нестабильная версия PVS\-Studio, поэтому моя вера в анализатор дрогнула\. "Эх, что\-то мы сломали в механизмах обработки неименованных перечислений", \- вздохнул я, и выписал этот случай в багтрекер как ошибку, приводящую к ложному срабатыванию\.

Я был абсолютно уверен, что ошибается именно анализатор\. Ведь всего несколькими строчками выше написано, что константа _CursorShowing_ равна 1\.

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

Я провёл внимательный обзор этого маленького участка кода и всё равно облажался\. Прав именно анализатор, а не человек\.

При подробном изучении ситуации выяснилось, что выше объявляется именованная константа _cursorShowing_, а в условии используется константа _CursorShowing_\. Разница только в первой букве\! В одном месте она строчная, а в другом прописная\.

Почему код компилируется? Потому, что константа _CursorShowing_ тоже существует\. Вот её объявление:

```cpp
class QWindowsCursor : public QPlatformCursor
{
public:
  enum CursorState {
    CursorShowing,
    CursorHidden,
    CursorSuppressed
  };
  ....
}
```

Как видите, константа _CursorShowing_ равна 0\. Поэтому анализатор PVS\-Studio абсолютно прав, сообщая, что условие _\(cursorInfo\.flags & CursorShowing\)_ не имеет смысла\. Условие является всегда ложным\.

Анализатор нашёл замечательную опечатку\. Любите статический анализ кода\! :\)