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::move(context), std::make_unique()) будет вычислен, но неопределенного поведения в context->task_runner() не будет, т.к. перемещеия в данном случае не будет.
Для примера:
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 вызывается именно чтобы переместить объект. Если объект при этом не перемещается, как вашем примере — это тоже ошибка, код который непонятно что делает.
А вот и нет
coliru.stacked-crooked.com/a/b1b6d06e6ed0a0cb
Тип аргумента T, а не T&&. Так что будет вызван move constructor
coliru.stacked-crooked.com/a/b1b6d06e6ed0a0cb
Тип аргумента T, а не T&&. Так что будет вызван move constructor
Тип аргумента — T&&, а параметра — T. Неопределенное поведение возникает при инициализации параметров, а не вычислении аргументов, что как раз не столь очевидно, как использование в аргументах выражений с побочными эффектами.
Мотивирующий пример:
clang++:
g++:
Очевидно, что сам вызов f(x,x) не подразумевает побочных эффектов при вычислении аргументов. Вот здесь то как раз и нужен статический анализатор, на что и мог указать автор.
Мотивирующий пример:
#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++ и C#, актуальны и для Java. Вы не планируете добавить в свой продукт поддержку явы?
Планируем. Добавляем. Если наш доклад возьмут на конференцию JPoint, то расскажем, как мы разрабатываем этот анализатор. Надеюсь, к этому моменту будет что-то, что можно показывать. А вообще, Java анализатор, уже даже какие-то ошибки находит, но статьи писать про это рано.
А поддержка C++, точнее добавления новых ворнингов планируется на этот год? Так как судя по ченджлогу активность вэтом направлении заметно снизилась. Понимаю, что уже достаточно очевидные вещи уже все проверяете, но думаю, еще есть что добавить, в особенности вещи связанные с использованием STD библиотеки.
Наша команда, как и прежде активно развивает возможности C++ анализатора. Например, готовится к выпуску сложная диагностика V1010, предназначенная для выявления использования недостоверных данных. А вообще, небольшое количество диагностик связано с тем, что сейчас в основном разработка ведётся «вширь». Усовершенствуется и обобщается Data Flow механизм, который будет использовать и в Java анализаторе. В результате, усовершенствования Data Flow анализа, старые диагностики начинают находить новые ошибки. Пример такого улучшения я недавно описывал в недавней статье "31 февраля".
Sign up to leave a comment.
Chromium: другие ошибки