Pull to refresh

Comments 15

По первому примеру не могу согласиться: не имеет значения в каком порядке будет «вычислен» std::move, он никак не модифицирует передаваемый аргумент, т.к. производится лишь преобразование типа ссылки — в стандарте указано (20.2.5):
template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept {
    return static_cast<remove_reference_t<T>&&>(t);
}
ЕЯПП, из-за того, что тип аргумента std::unique_ptr<FileSystemOperationContext>, проблема не в std::move, а в move-конструктре, который будет неявно вызван.
Так точно, проблема в инициализации параметров, где уже собственно и происходит вызов перемещающего конструктора. А само вычисление аргументов в данном случае не приводит к модификации указателя. В объяснении из статьи использована неверная терминология.
Для примера:
CreateSnapshotFile(
      (std::move(context), std::make_unique<FileSystemOperationContext>()), url,
      base::Bind(
        &NativeMediaFileUtil::CreatedSnapshotFileForCreateOrOpen,
        base::RetainedRef(context->task_runner()),
        file_flags, callback));

Аргумент (std::move(context), std::make_unique()) будет вычислен, но неопределенного поведения в context->task_runner() не будет, т.к. перемещеия в данном случае не будет.
Тем не менее, обычно std::move вызывается именно чтобы переместить объект. Если объект при этом не перемещается, как вашем примере — это тоже ошибка, код который непонятно что делает.
std::move делает ровно то, что он делает — преобразование типа значения в xvalue. Как использовать полученное значение — для перемещения, чтения, модификации без перемещения и т.п. — уже не касается самой функции.
Тип аргумента — T&&, а параметра — T. Неопределенное поведение возникает при инициализации параметров, а не вычислении аргументов, что как раз не столь очевидно, как использование в аргументах выражений с побочными эффектами.
Мотивирующий пример:
#include <iostream>

struct C {
    C(int&& i) : x(i) {}
    C(int& i) : x(i) {++i;}
    int x;
};

int f1(const C& c, int i) { return c.x+i; }
int f2(int i, const C& c) { return c.x+i; }

int main() {
    int x = 1, y = 1;
    std::cout << f1(1,1) << std::endl;
    std::cout << f1(x,x) << std::endl;
    std::cout << f2(1,1) << std::endl;
    std::cout << f2(y,y) << std::endl;
}

clang++:
2
3
2
2

g++:
2
2
2
3


Очевидно, что сам вызов f(x,x) не подразумевает побочных эффектов при вычислении аргументов. Вот здесь то как раз и нужен статический анализатор, на что и мог указать автор.
Бесконечно можно смотреть на три вещи: горящий огонь, бегущую воду и на то, как PVS-Studio передаёт привет разработчикам компании Google.

Вы и ваш продукт настолько круты, что в процессе чтения ваших статей уже не первый раз ловлю себя на сожалении о том, что редко пишу на сях, и поэтому не использую PVS Studio. Очень надеюсь, что вы сможете достучаться до Google.

У меня эти статьи вызывают несколько иные мысли. Как же страшно жить, когда повсюду нас окружают программы, написанные на C++ без анализа PVS Studio.
Многие проверки, которые вы делаете в C++ и C#, актуальны и для Java. Вы не планируете добавить в свой продукт поддержку явы?
Планируем. Добавляем. Если наш доклад возьмут на конференцию JPoint, то расскажем, как мы разрабатываем этот анализатор. Надеюсь, к этому моменту будет что-то, что можно показывать. А вообще, Java анализатор, уже даже какие-то ошибки находит, но статьи писать про это рано.
А поддержка C++, точнее добавления новых ворнингов планируется на этот год? Так как судя по ченджлогу активность вэтом направлении заметно снизилась. Понимаю, что уже достаточно очевидные вещи уже все проверяете, но думаю, еще есть что добавить, в особенности вещи связанные с использованием STD библиотеки.
Наша команда, как и прежде активно развивает возможности C++ анализатора. Например, готовится к выпуску сложная диагностика V1010, предназначенная для выявления использования недостоверных данных. А вообще, небольшое количество диагностик связано с тем, что сейчас в основном разработка ведётся «вширь». Усовершенствуется и обобщается Data Flow механизм, который будет использовать и в Java анализаторе. В результате, усовершенствования Data Flow анализа, старые диагностики начинают находить новые ошибки. Пример такого улучшения я недавно описывал в недавней статье "31 февраля".
Сейчас мы ещё дополнительно отвлеклись на полноценную поддержку Keil и IAR. Плюс поддержка macOS на подходе. Скоро пойдут публикации о разных новых возможностях С++ анализатора. Можно делать предзаказы.
Sign up to leave a comment.