2016-03-22 3 views
2

Есть ли способ сделать компилятор (лязг ++ или г ++) информировать друг о следующих ситуациях:Предупреждение при Rvalue объявленная переменная выходит из области видимости будучи не переехал из

static_assert(!std::is_lvalue_reference<T>::value); 
void g(T); 
void f(T x) 
{ 
    T y = x; 
#if 0 // turns warning off 
    g(std::move(x)); 
#endif 
} // warning here: x goes out of scope, but not moved from 

или

static_assert(!std::is_reference<T>::value); 
T f() 
{ 
    T x; 
    T y = x; 
#if 0 // turns warning off 
    return x; 
#else 
    return {}; 
#endif 
} // warning here: x goes out of scope, but not moved from 

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

void f() 
{ 
    T x; 
    T y = std::move(x); 
    T z = x; // warning here: x is used since it has been moved from 
} 

Переменные таких классов, не подлежащих копированию, как std::unique_ptr редко используются повторно после их кражи.

Было бы здорово, если бы предупреждения, описанные выше, были бы доступны как переменная, вызванная через #pragma, или атрибут или глобально для всех переменных, которые являются классами с пользовательским оператором и конструктором присваивания.

Иногда трудно следить за продолжительностью жизни переменной.

В современных компиляторах имеется форма SSA-формы (статическая одиночная заданная форма) промежуточного представления (например, AST). Поэтому я считаю, что компиляторам не слишком сложно обнаружить вышеописанные ситуации.

+0

«при перемещении из переменной, используемой еще раз», конечно, если вы перемещаете содержимое, вы должны предположить, что переменная находится в неопределенном состоянии - даже если это всего лишь целое число, вы не должны использовать его снова *. И если вам нужно использовать его, зачем вы его начинаете? –

+1

@JohnBargman, нет, это не то, что происходит. Для целого числа он не изменится, поскольку 'unique_ptr' имеет полностью определенное состояние (оно пустое), а для большинства других типов оно« действительное, но неуказанное ». –

+0

@Orient, что вы имеете в виду «T - это prvalue»? T - тип, а не выражение, так что это не имеет смысла. Для каких условий вы хотите, чтобы предупреждение срабатывало? –

ответ

2

Нет, сегодня с GCC или Clang нет способа сделать это.

Новый атрибут [[nodiscard]], приходящий на C++ 17, смутно связан, но не то же самое и не может использоваться ни для одного из ваших случаев.