﻿# Как PVS\-Studio защищает от поспешных правок кода, пример N3

Продолжаем серию маленьких заметок про то, как анализатор PVS\-Studio может быстро находить новые ошибки в коде\. При условии, конечно, что он регулярно используется :\)\. Итак, перед нами очередной баг в проекте Blender\.

![0922_Blender_prevents_rash_code_changes_N3_ru/image1.png](https://import.viva64.com/docx/blog/0922_Blender_prevents_rash_code_changes_N3_ru/image1.png)

Ради развлечения я мониторю проект [Blender](https://github.com/blender/blender)\. Каждый день мне приходит отчёт [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/) с предупреждениями, относящимися к новому коду\. Иногда какая\-то ошибка мне нравится, и я пишу про неё\. Именно этим я занимаюсь и сейчас :\)\.

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

В этот раз моё внимание привлекло два предупреждения PVS\-Studio, указывающих на одну строчку кода:

* \[CWE\-480\] [V616](https://pvs-studio.ru/ru/docs/warnings/v616/): The 'OB\_MODE\_OBJECT' named constant with the value of 0 is used in the bitwise operation\. transform\_snap\_object\.c [480](https://github.com/blender/blender/commit/52be06301257a82a1b4a5746e91ff60daa637ded#diff-ef92fd8979755e531c56eea8799c6c6f72415db032b44f5486a4ed39c2e2ab42R480)
* \[CWE\-571\] [V560](https://pvs-studio.ru/ru/docs/warnings/v560/): A part of conditional expression is always true: \!\(base\-\>object\-\>mode & OB\_MODE\_OBJECT\)\. transform\_snap\_object\.c [480](https://github.com/blender/blender/commit/52be06301257a82a1b4a5746e91ff60daa637ded#diff-ef92fd8979755e531c56eea8799c6c6f72415db032b44f5486a4ed39c2e2ab42R480)

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

```cpp
if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {
```

Если вы прочитали сообщения анализатора, то, думаю, уже догадались, в чём дело\. Однако если просто смотреть на этот код, то он кажется совершенно нормальным\. Скажем так, эта строчка может не вызвать ни у кого подозрения в процессе обзора кода\.

Чтобы понять, что код неверен, нужно посмотреть, как объявлена именованная константа в перечислении _eObjectMode_:

```cpp
typedef enum eObjectMode {
  OB_MODE_OBJECT = 0,
  OB_MODE_EDIT = 1 << 0,
  OB_MODE_SCULPT = 1 << 1,
  OB_MODE_VERTEX_PAINT = 1 << 2,
  OB_MODE_WEIGHT_PAINT = 1 << 3,
  OB_MODE_TEXTURE_PAINT = 1 << 4,
  OB_MODE_PARTICLE_EDIT = 1 << 5,
  OB_MODE_POSE = 1 << 6,
  OB_MODE_EDIT_GPENCIL = 1 << 7,
  OB_MODE_PAINT_GPENCIL = 1 << 8,
  OB_MODE_SCULPT_GPENCIL = 1 << 9,
  OB_MODE_WEIGHT_GPENCIL = 1 << 10,
  OB_MODE_VERTEX_GPENCIL = 1 << 11,
} eObjectMode;
```

Итак, константа _OB\_MODE\_OBJECT_ равна нулю\! Ещё раз взглянем на условие:

```cpp
if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {
```

Получается, что результат операции "побитовый И" \(&\) всегда равен 0\. Про это первое сообщение анализатора\. 

Применим к 0 оператор "\!", и получается, что перед нами выражение:

```cpp
if (is_object_active && true) {
```

Про то, что часть выражения всегда истинна, нам говорит уже второе предупреждение PVS\-Studio\.

Скорее всего, правильным вариантом будет:

```cpp
if (is_object_active && base->object->mode != OB_MODE_OBJECT) {
```

Впрочем, я не уверен, так как не разбираюсь в исходном коде Blender\. Задача анализатора – указать на ошибку, а что с ней делать, должен решать уже разработчик проекта\.

Спасибо за внимание и подписывайтесь на мой Twitter: [@Code\_Analysis](https://twitter.com/Code_Analysis)\. 

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

1. [Бесплатные варианты лицензирования PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/0614/)\.
1. [Как внедрить статический анализатор кода в legacy проект и не демотивировать команду](https://pvs-studio.ru/ru/blog/posts/0743/)\.
1. [Развитие инструментария С\+\+ программистов: статические анализаторы кода](https://pvs-studio.ru/ru/blog/posts/cpp/0873/)\.