Комментарии 11
Так а PVS Studio починили? Или так и будет выдавать V595 после static_cast
?
Я немного не понимаю ваш вопрос, но могу попытаться дать ответ на него. Если мой ответ не помог, то попробуйте задать свой вопрос по-другому
Предупреждение было выдано на разыменование указателя xdriver, который после использования проверяется на валидность. Здесь анализатор PVS-Studio верно сработал.
В самой статье приведено три варианта исправления найденной проблемы:
С сохранением замысла исходного кода. В таком варианте происходит замена static_cast на dynamic_cast и перемещение проверки валидности указателя в место до его разыменования.
С изменением архитектуры классов. В таком варианте интерфейс Shutdown вынесен в базовый класс в виде чистой виртуальной функции, а AudioSystem::DestroyDriver сделан невиртуальным.
Использование 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. Это может означать одно из двух:
Возникнет ошибка, если указатель будет равен NULL.
Программа всегда работает корректно, так как указатель всегда не равен NULL. Проверка является лишней.
Если говорить про варианты, которые указаны в цитате, то для решения проблемы в первом варианте нужно пересмотреть место срабатывания на наличие неправильного расположения проверки и/или использования, а во втором варианте просто убрать лишнюю проверку
Иначе говоря, ситуация "проверили, использовали, проверили ещё раз" под диагностику тоже подпадает, потому что подпадает под второй случай?
интуитивно я б ожидал там диагностики "condition is always true", типа как в
a=1;
if (a > 0) { ... }
Такое диагностическое правило так же есть в анализаторе PVS-Studio.
V547. Expression is always true/false.
Да, все верно
Мне интересно узнать, что вы думаете об этом фрагменте.
Непонятно зачем вообще нужен Shutdown, если уже есть деструктор. А тогда встаёт вопрос зачем нужен метод DestroyDriver.
Гадание на пяти строчках: о чем молчит программа