简体   繁体   English

如何检查变量是否仍然有效或在其上使用了 std::move?

[英]How to check if variable is still valid or std::move was used on it?

I am aware that after using std::move the variable is still valid, but in an unspecified state.我知道在使用std::move该变量仍然有效,但处于未指定状态。

Unfortunately, recently I have come across several bugs in our code base where a function was accessing the moved variable, and weird things were happening.不幸的是,最近我在我们的代码库中遇到了几个错误,其中一个函数正在访问被移动的变量,并且发生了一些奇怪的事情。 These issues were extremely hard to track down.这些问题极难追查。

Is there any compiler option (in clang) or any way to throw an error either during runtime or compilation?是否有任何编译器选项(在 clang 中)或在运行时或编译期间以任何方式抛出错误?

Some things that may help :一些可能有帮助的事情:


Code changes that can make such bugs easy to track down:可以使此类错误易于追踪的代码更改:

I'm assuming that if you're using std::move on something, it is (not always) a heavy container.我假设如果你在某些东西上使用std::move ,它(并不总是)是一个沉重的容器。

If so, try to use std::unique_ptr<T> to create it.如果是这样,请尝试使用std::unique_ptr<T>来创建它。 Calls to movers must explicitly use std::move , which is easy to spot.对移动者的调用必须显式使用std::move ,这很容易被发现。 And other non-owning access functions can just work with .get() .其他非拥有访问功能可以与.get() You can also check for nullability and throw if it's nullptr at any point where you need to access it.您还可以检查可空性并在您需要访问它的任何时候抛出它是否为nullptr

I am aware that after using std::move the variable is still valid, but in an unspecified state.我知道在使用 std::move 后,该变量仍然有效,但处于未指定状态。

This is not a universal truth.这不是普遍真理。 More generally, the object that was moved from is in whatever state in which the move constructor / assignment operator left it.更一般地,被移动的对象处于移动构造函数/赋值运算符离开它的任何状态。

The standard library does have the guarantee that you describe at minimum.标准库确实具有您所描述的最低限度的保证。 But it is also possible to implement a member function for your class which doesn't abide by it, and leaves the moved from object in an invalid state.但是也可以为您的类实现一个不遵守它的成员函数,并使移动的对象处于无效状态。 It is however a good design choice to implement move operations in the way you describe.然而,以您描述的方式实现移动操作是一个很好的设计选择。

How to check if variable is still valid or std::move was used on it?如何检查变量是否仍然有效或在其上使用了 std::move?

There is no way to do such check in general within the language.在语言中一般无法进行此类检查。

Is there any compiler option (in clang) or any way to throw an error either during runtime or compilation?是否有任何编译器选项(在 clang 中)或在运行时或编译期间以任何方式抛出错误?

Note that using a variable after a move is not necessarily a bug at all, but can instead be an entirely correct thing to do.请注意,在移动后使用变量不一定是错误,而是完全正确的做法。 Some types specify exactly the state of the moved from object ( std::unique_ptr for example) and others which have the validity guarantee can be used in ways that have no pre-conditions (such as calling container.size() ).某些类型准确指定了从对象移动的状态(例如std::unique_ptr ),而其他具有有效性保证的类型可以以没有先决条件的方式使用(例如调用container.size() )。

As such, using a moved from object is only a problem if that violates a pre-condition, which would result in undefined behaviour.因此,使用移动自对象只有在违反先决条件时才会出现问题,这将导致未定义的行为。 Clang and other compilers have runtime sanitisers that may be able to catch some undefined behaviour. Clang 和其他编译器具有运行时清理器,可以捕获一些未定义的行为。 There are also many warning options and static analysers that diagnose cases where bugs are likely.还有许多警告选项和静态分析器可以诊断可能存在错误的情况。

Using them is a very good idea, but you should not rely solely on them because they won't be able to find all bugs.使用它们是一个很好的主意,但您不应该仅仅依赖它们,因为它们无法找到所有错误。 The programmer still needs to be careful when writing the program, and needs to compare it with the rules of the language.程序员在写程序的时候还是要小心,需要和语言的规则做比较。 Following common idioms such as RAII, avoiding bare owning pointers (and other resource handles) goes a long way in avoiding typical bugs.遵循诸如 RAII 之类的常见习语,避免拥有指针(和其他资源句柄)对于避免典型错误大有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM