Как стать автором
Обновить

Комментарии 11

Так а PVS Studio починили? Или так и будет выдавать V595 после static_cast?

Я немного не понимаю ваш вопрос, но могу попытаться дать ответ на него. Если мой ответ не помог, то попробуйте задать свой вопрос по-другому

Предупреждение было выдано на разыменование указателя xdriver, который после использования проверяется на валидность. Здесь анализатор PVS-Studio верно сработал.
В самой статье приведено три варианта исправления найденной проблемы:

  1. С сохранением замысла исходного кода. В таком варианте происходит замена static_cast на dynamic_cast и перемещение проверки валидности указателя в место до его разыменования.

  2. С изменением архитектуры классов. В таком варианте интерфейс Shutdown вынесен в базовый класс в виде чистой виртуальной функции, а AudioSystem::DestroyDriver сделан невиртуальным.

  3. Использование 2 варианта с идиомой NVI.

Если воспользоваться одним из вариантов, то проблемы уже не будет, и PVS-Studio не будет выдавать предупреждение.

Пробую задать по-другому:

  assert_not_null(driver);
  auto xdriver = static_cast<XAudio2AudioDriver*>(driver);
  xdriver->Shutdown();
  assert_not_null(xdriver);

в строчке 1 проверяется, что driver не nullptr

в строчке 2 xdriver=static_cast<>(driver) это, как вы сами пишете, никаких динамических проверок не производит, и "при этом результирующий указатель также ненулевой", раз уж driver был ненулевой

в строчке 3 xdriver разыменовывается

в строчке 4 xdriver проверяется на nullptr и PVS-Studio предупреждает "V595 The 'xdriver' pointer was utilized before it was verified against nullptr"

В то время как очевидно, что 'xdriver' was verified against nullptr в строчке 1 и в строчке 3 его можно совершенно безопасно разыменовывать.

Собственно, я и спросил, починили ли PVS-Studio распознавать что если какой-то указатель ненулевой, то это свойство сохраняется при cast-ах (кроме dynamic_cast)

Данная диагностика не направлена на отслеживание валидности указателя. Анализатор выдает предупреждение на случаи, когда указатель используется, а после проверяется.
Возможно, так же поможет разобраться в вопросе документация и отдельная статья "Пояснение про диагностику V595".

Возможно, речь вот о чём. PVS-Studio же, по идее, не должна выдавать V595 (по крайней мере, на уровне выше Low) на код вида

assert_not_null(ptr);
ptr->do_something();
assert_not_null(ptr);

потому как проверка перед разыменованием есть, и проблема только в том, что вторая проверка избыточна. Но при этом, если в середину вставить static_cast (который на то, равен ли указатель null, никак не влияет), аналогичный код начинает выдавать ошибку. Это корректно, или имеет смысл добавить исключение?

В обоих указанных вами случаях срабатывание будет выдано верно, потому что сама диагностика на это и рассчитана:

Анализатор заметил в коде следующую ситуацию. В начале, указатель используется. А уже затем этот указатель проверяется на значение NULL. Это может означать одно из двух:

  1. Возникнет ошибка, если указатель будет равен NULL.

  2. Программа всегда работает корректно, так как указатель всегда не равен NULL. Проверка является лишней.

Если говорить про варианты, которые указаны в цитате, то для решения проблемы в первом варианте нужно пересмотреть место срабатывания на наличие неправильного расположения проверки и/или использования, а во втором варианте просто убрать лишнюю проверку

Иначе говоря, ситуация "проверили, использовали, проверили ещё раз" под диагностику тоже подпадает, потому что подпадает под второй случай?

интуитивно я б ожидал там диагностики "condition is always true", типа как в

a=1;
if (a > 0) { ... }

Такое диагностическое правило так же есть в анализаторе PVS-Studio.

V547. Expression is always true/false.

Да, все верно

Мне интересно узнать, что вы думаете об этом фрагменте.

Непонятно зачем вообще нужен Shutdown, если уже есть деструктор. А тогда встаёт вопрос зачем нужен метод DestroyDriver.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий