﻿# PVS\-Studio 7\.24: Unity, продвинутые механизмы подавления и многое другое

Вышел новый релиз PVS\-Studio — 7\.24\. В нём мы улучшили анализ проектов на Unity, добавили новые возможности работы с файлами подавления \(\*\.suppress\), реализовали ряд диагностик и сделали многое другое\. Подробности в этой заметке\.

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

**Улучшения анализа проектов на Unity**

Для многих классов игрового движка Unity оператор '\=\=' перегружен особым образом\. Наиболее интересной особенностью перегрузки является тот факт, что сравнение с _null_ может вернуть _true_, даже если сравниваемая ссылка не является нулевой\. Пример:

```cpp
void Start()
{
  GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
  Instantiate(obj);

  if (obj == null)
    Debug.Log("obj == null before destroy");

  DestroyImmediate(obj);

  if (obj == null)
    Debug.Log("obj == null after destroy");

  if (ReferenceEquals(obj, null))
    Debug.Log("obj is really null");

  if (obj is null)
    Debug.Log("obj is really null 2");
}
```

Если вы работаете с Unity, то наверняка сможете сказать, что на экран консоли будет выведена единственная надпись: "obj \=\= null after destroy"\. Всё потому, что оператор '\=\=' при сравнении с _null_ возвращает _true_, если сравниваемый объект уничтожен\.

Новая версия анализатора лучше понимает такие особенности\. В первую очередь это позволяет убрать ложные срабатывания о разыменовании нулевых ссылок\. Также теперь PVS\-Studio отслеживает обращения к методам и свойствам потенциально уничтоженных объектов\. Такие обращения могут приводить к выбрасыванию исключений, и для их поиска мы добавили отдельное правило [V3188](https://pvs-studio.ru/ru/docs/warnings/v3188/)\.

Мы планируем и дальше улучшать возможности анализа проектов, использующих Unity, дорабатывая имеющиеся механизмы и реализуя новые диагностики\. Обязательно [пишите нам](https://pvs-studio.ru/ru/about-feedback/) если у вас есть идеи по поводу того, какие ошибки анализатору стоит находить в таких проектах\.

**Продвинутые механизмы работы с файлами подавления в Visual Studio**

В плагине для Visual Studio был расширен интерфейс для работы с [файлами подавления](https://pvs-studio.ru/ru/docs/manual/0032/) \(\*\.suppress\)\. Раньше предполагалось, что в проекте может быть только один suppress\-файл\. Теперь же к каждому проекту может относиться несколько файлов подавления\.

Ниже перечислены несколько нововведений\. 

1\) Можно добавлять предупреждения в конкретные suppress\-файлы:

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

2\) Можно выбирать suppress\-файлы, предупреждения из которых будут отображены в таблице: 

![1044_PressRelease_7_24_ru/image3.png](https://import.viva64.com/docx/blog/1044_PressRelease_7_24_ru/image3.png)

3\) Подавленные предупреждения можно также перемещать между suppress\-файлами:

![1044_PressRelease_7_24_ru/image4.png](https://import.viva64.com/docx/blog/1044_PressRelease_7_24_ru/image4.png)

Эти возможности позволяют реализовывать новые сценарии работы с файлами подавления\. К примеру, можно использовать один suppress\-файл для предупреждений, оставленных "на потом", и ещё один — для ложных срабатываний\.

Подробнее с этими и другими возможностями вы можете ознакомиться в [документации](https://pvs-studio.ru/ru/docs/manual/0032/#VisualStudioSuppression)\.

**Новые возможности подавления предупреждений из командной строки**

В утилитах PVS\-Studio\_Cmd\.exe и pvs\-studio\-dotnet появился новый режим — suppression\. С помощью него можно производить различные операции с [файлами подавления](https://pvs-studio.ru/ru/docs/manual/0032/) \(\*\.suppress\)\. 

К примеру, можно создать для каждого проекта из решения новый suppress\-файл:

```cpp
PVS-Studio_Cmd.exe suppression -m CreateEmptySuppressFiles ^
                               -t JulietTestSuite.sln ^
                               -P myPrefix%projName%myPostfix.suppress
```

В результате выполнения такой команды в каждый проект решения будет добавлен пустой suppress\-файл, имя которого генерируется на основе имени соответствующего проекта\.

Ещё одной интересной возможностью является подавление предупреждений, соответствующих определённым критериям:

```cpp
PVS-Studio_Cmd.exe suppression -m Suppress ^
                               -t JulietTestSuite.sln ^
                               -P myPrefix%projName%myPostfix.suppress ^
                               -R  JulietTestSuite.plog ^
                               --groups "GA:3|OWASP"
```

Указанная команда подавит предупреждения из отчёта JulietTestSuite\.plog в suppress\-файлы, соответствующие паттерну, переданному через параметр '\-P'\. При этом подавлены будут только предупреждения 3 уровня группы General Analysis и все предупреждения группы OWASP\.

Таким же образом можно и "снять подавление" с определённых предупреждений — для этого в качестве значения параметра '\-m' необходимо передать 'UnSuppress'\.

Эти и другие возможности нового режима подробно описаны в [документации](https://pvs-studio.ru/ru/docs/manual/0032/#WindowsCLISuppressionMode)\.

**Учёт оператора null\-forgiving \('\!'\) в C\#**

В C\# 9 в язык добавили возможность условного разделения ссылочных типов на допускающие и не допускающие _null_\. Подробности — в [официальной документации](https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references)\.

Когда ссылочная переменная может иметь значение _null_, к имени его типа добавляется '?'\. Если же в конкретной ситуации такое выражение точно не возвращает нулевую ссылку, разработчики могут использовать оператор [null\-forgiving \('\!'\)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving)\. Пример:

```cpp
bool _returnText = false;

void Foo()
{
  _returnText = true;

  string value = GetText()!;
  _ = value.Length;
}

// may return null
private string? GetText()
{
  return _returnText ? "some text" : null;
}
```

Метод _GetText_ в некоторых обстоятельствах действительно может возвращать _null_, однако результат его вызова внутри _Foo_ точно является строкой "some text"\. Пометив вызов с помощью постфиксного '\!', разработчик сообщает компилятору, что выражение не равно _null_\.

Мы долго обдумывали необходимость учёта оператора null\-forgiving при анализе\. С одной стороны, он не даёт гарантий того, что выражение действительно не будет равно _null_\. С другой — он является способом подавления ложных предупреждений компилятора о небезопасном разыменовании\. Стоит ли ругаться там, где похожее предупреждение компилятора уже было подавлено?

В итоге анализатор всё же начал учитывать оператор null\-forgiving при выдаче предупреждений\. Теперь PVS\-Studio не будет выдавать предупреждения о разыменовании потенциально нулевой ссылки, если выражение размечено с помощью '\!'\. Однако предупреждение всё же будет показано, если _null_ является единственным возможным значением выражения\.

**Новые диагностики**

C, C\+\+

* [V1095](https://pvs-studio.ru/ru/docs/warnings/v1095/)\. Usage of potential invalid handle\. The value should be non\-negative\.
* [V1096](https://pvs-studio.ru/ru/docs/warnings/v1096/)\. Variable with static storage duration is declared inside the inline function with external linkage\. This may lead to ODR violation\.
* [V1097](https://pvs-studio.ru/ru/docs/warnings/v1097/)\. Line splice results in a character sequence that matches the syntax of a universal\-character\-name\. Using this sequence lead to undefined behavior\.

C\#

* [V3187](https://pvs-studio.ru/ru/docs/warnings/v3187/)\. Parts of an SQL query are not delimited by any separators or whitespaces\. Executing this query may lead to an error\.
* [V3188](https://pvs-studio.ru/ru/docs/warnings/v3188/)\. The value of an expression is a potentially destroyed Unity object or null\. Member invocation on this value may lead to an exception\.
* [V3189](https://pvs-studio.ru/ru/docs/warnings/v3189/)\. The assignment to a member of the readonly field will have no effect when the field is of a value type\. Consider restricting the type parameter to reference types\.

**Личный кабинет пользователя**

Недавно мы добавили на сайт возможность создавать свой аккаунт и заходить в свой личный кабинет\. Кнопки регистрации/авторизации можно найти в шапке сайта, наведя курсор на иконку:

![1044_PressRelease_7_24_ru/image5.png](https://import.viva64.com/docx/blog/1044_PressRelease_7_24_ru/image5.png)

Личный кабинет позволяет:

* просматривать список своих триальных ключей;
* подписываться на комментарии к статьям;
* получать оповещения об ответах на ваши комментарии;
* настраивать подписки на рассылки о новых статьях и релизах\.

![1044_PressRelease_7_24_ru/image6.png](https://import.viva64.com/docx/blog/1044_PressRelease_7_24_ru/image6.png)

В общем, приглашаю всех [регистрироваться](https://pa.pvs-studio.com/ru/account/register/) :\)\.

Подробнее о личном кабинете можете прочитать в [заметке](https://pvs-studio.ru/ru/blog/posts/1041/)\.

**Статьи**

Для тех, кто пишет на C\+\+:

* [64\-битные ошибки: LONG, LONG\_PTR и привет из прошлого](https://pvs-studio.ru/ru/blog/posts/cpp/1036/)
* [Приключения капитана Блада: потонет ли Арабелла?](https://pvs-studio.ru/ru/blog/posts/cpp/1033/)
* [Тонкости C\+\+: итак, вы объявили класс\.\.\.](https://pvs-studio.ru/ru/blog/posts/cpp/1031/)

Для тех, кто пишет на C\#:

* [Зачем при изменении сборки менять её версию или как сломать Visual Studio одной командой](https://pvs-studio.ru/ru/blog/posts/csharp/1039/)
* [Парсинг string в enum ценой в 50 Гб: разбираем уязвимость CVE\-2020\-36620](https://pvs-studio.ru/ru/blog/posts/csharp/1038/)
* [Нужно ли проверять библиотеки перед их использованием? Разберём на примере MudBlazor](https://pvs-studio.ru/ru/blog/posts/csharp/1032/)

Разное:

* [Личный кабинет PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/1041/)
* [Reddit для программистов](https://pvs-studio.ru/ru/blog/posts/1040/)
* [Что нельзя найти с помощью статического анализа](https://pvs-studio.ru/ru/blog/posts/1037/)
* [Хорошо ли ChatGPT ищет ошибки в коде?](https://pvs-studio.ru/ru/blog/posts/1035/)

\*\*

Загрузить актуальную версию PVS\-Studio можно [здесь](https://pvs-studio.ru/ru/pvs-studio/try-free/)\.

Если хотите получать пресс\-релизы по почте, [подписывайтесь на рассылку](https://pvs-studio.ru/ru/subscribe/)\.