G++ :检测到std后使用::移动
由于使用了std :: vector,我刚刚在代码中发现了一个错误。该代码类似于:
std::vector<SomeObject> v1;
//fill v1;
this->v2=std::move(v1);
for(unsigned int i=0; i<v1.size(); i++)
{
//the code in the for loop was not executed
}
行为不足为奇(V1的状态是未定义的,只要有效;因此空置向量似乎是合乎逻辑的选择)。
我的问题是:在移动变量后使用变量时,是否有可能让我警告我?如果是这样,我应该添加哪个标志?
NB:我认为无法确保检测到这种警告(我认为这等同于停止问题,这是无法解决的)。但是,如果我在示例(例如,可以证明又一次使用后使用)警告,或者如果G ++无法证明它是安全的,那将非常有用。
非常感谢
I just found an error in my code due to using an std::vector after having moved it. The code was something like :
std::vector<SomeObject> v1;
//fill v1;
this->v2=std::move(v1);
for(unsigned int i=0; i<v1.size(); i++)
{
//the code in the for loop was not executed
}
The behavior is not surprising (the state of v1 is undefined, as long as it is valid; so an empty vector seems a logical choice).
My question is : is it possible to make g++ give me a warning when using a variable after moving it? If so, what flag should I add?
NB : I suppose it is not possible to guarantee the detection of such warning (it would, I think, be equivalent to the halting problem, that can't be solved for the general case). But it would already be very useful if I get a warning either for simple cases like the example (use after move can be proven), or if I get a warning when g++ can't prove that it is safe.
Thanks a lot in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为GCC对此没有诊断。
但是,Clang静态分析仪和Clang-Tidy做到了。如果您在此类代码上运行它们(两者),并启用了所有诊断,则获得(摘录):
请参阅
其他衬里和静态分析仪可能已经实施了类似的诊断。 GCC现在还具有静态分析仪(使用
-Fanalyzer
启用),但似乎还没有实现的诊断。但是,此类诊断可能很容易是错误的阳性(这可能是编译器不作为直接编译器警告实施它们的原因)。
例如,
std :: simolor_ptr
从移动时具有非常清晰的行为。最终的状态是一个空的std :: simolor_ptr
。如果是稍后检查是否为空,则没有问题。同样,搬迁后可以重复使用所有行为良好类型的对象。移动后立即可以简单地指定。但是例如,分配新状态应该很好。
I don't think GCC has a diagnostic for that.
However the Clang static analyzer and Clang-tidy do. If you run them (both) on such code with all diagnostics enabled you get (excerpt):
See godbolt. The first being the clang-tidy diagnostic and the second being the static analyzer diagnostic.
Other linters and static analyzers probably have similar diagnostics implemented. GCC also now has a static analyzer (enabled with
-fanalyzer
), but it doesn't seem to have a diagnostic for this implemented yet.Such diagnostics may however easily be false-positives (which may be a reason that the compilers don't implement them as direct compiler warnings).
For example
std::unique_ptr
has a very clear behavior when moved from. The resulting state is that of an emptystd::unique_ptr
. If it is then later checked for whether it is empty or not, there is no issue.Also, objects of all well-behaved types can be reused after a move. The state immediately after the move may simply be unspecified. But e.g. assigning a new state should be fine.
我认为这不可能。移动语义并未指定已移动的对象的状态。这取决于实施。
例如,对向量分配的移动分配非常合理的实现是在两个向量之间交换数据。因此,在您的代码中,
v1.size()
将是移动分配之前的v2
的大小。谁说班级没有指定语义?使用后使用是完全合理的。显然,在STL中,移动构造函数使移动的容器空移动。但这仍然具有完全有效的
v1.size()
的0
。每个移动的对象都有一些有效使用的方法。至少应始终允许分配。对于STL容器,我希望大小()在所有情况下也有效,但也许不会返回您的期望。但是,编译器应该如何知道哪些方法可以保存在移动对象上?
为了使编译器发出感官警告,我认为编译器(或C ++)需要引入一些新属性,并且STL需要注释它的移动构造函数 /移动分配。这样,编译器可以知道移动构造函数 /分配是否遵循有效但未指定状态的某个语义< / em>。
I do not believe this is possible in general. The move semantic does not specify the state of an object that was moved from. That depends on the implementation.
For example a very reasonable implementation for the move assignment of vector is to swap the data between the two vectors. So in you code example the
v1.size()
would be the size ofv2
from before the move assignment. Who is to say the class does not specify that semantic? It would be perfectly reasonable to use-after-move.Apparently in the STL the move constructor leaves the moved from container empty. But that would still have a perfectly valid
v1.size()
of0
.Every moved-from object has some methods that are valid to use. At a minimum assignment should always be allowed. For STL containers I expect size() to also be valid in all cases but maybe not return what you expect. But really how is the compiler supposed to know which methods are save to call on moved-from objects?
For the compiler to give sensical warnings I think the compiler (or C++) needs to introduce some new attributes and the STL needs to annotate it's move constructors / move assignment. That way the compiler could know if a move constructor / assignment follows a certain semantic beyond valid but unspecified state.