编译器能否自动生成std :: move以自动使用左值? [英] Can compiler generate std::move for a last use of lvalue automatically?
问题描述
在r值参考文章中经常看到这样的代码:
无效g(X);
void f()
{
X b;
g(b); //仍需要b的值
…
g(std :: move(b)); //现在全部用b完成;授予移动
的权限
编译器能否自动生成此优化,即检测到假设编译器对X类的移动,复制或销毁如何实现一无所知,那么l值将无论如何都会被销毁并可能被移走,或者这是否违反标准? / p>
如果允许这种优化,实际上是由某些编译器执行吗?
否。考虑:
,使用X = std :: shared_ptr< int> ;;
无效g(X);
void f(){
X b = std :: make_shared< int>();
int& i = * b;
g(b); //上次使用 b
i = 5;
}
通常,编译器不能假定更改副本,移动和复制的语义 X
的析构函数将是合法的更改,无需对围绕 b
使用的所有代码进行分析(即, f
, g
以及其中使用的所有类型)。
实际上,在某些情况下可能需要对整个程序进行分析:
使用X = std :: shared_ptr< std :: lock_guard< std :: mutex>> ;;
std :: mutex i_mutex;
int i;
无效g(X);
void f(){
X b = std :: make_shared< std :: lock_guard< std :: mutex>>(i_mutex);
g(b); //上次使用 b
i = 5;
}
如果 b
为移动后,这将引发与其他线程的数据争夺,这些线程使用 i_mutex
同步对 i
的访问。
A code like this is often seen in r-value references articles:
Dave Abrams: Move It With Rvalue References
void g(X);
void f()
{
X b;
g(b); // still need the value of b
…
g( std::move(b) ); // all done with b now; grant permission to move
}
Could a compiler generate this optimization automatically, i.e. to detect a l-value is going to be destructed anyway and could be moved from, or would this be a violation of the standard, assuming a generic case the compiler does not know anything about how is move, copy or destruct implemented for the X class?
If such optimization is allowed, is it performed by some compiler in practice?
No. Consider:
using X = std::shared_ptr<int>;
void g(X);
void f() {
X b = std::make_shared<int>();
int &i = *b;
g(b); // last use of 'b'
i = 5;
}
In general, the compiler cannot assume that altering the semantics of copies, moves and destructors of X
will be a legitimate change without performing analysis on all the code surrounding the use of b
(i.e., the whole of f
, g
, and all the types used therein).
Indeed, in some cases whole-program analysis may be necessary:
using X = std::shared_ptr<std::lock_guard<std::mutex>>;
std::mutex i_mutex;
int i;
void g(X);
void f() {
X b = std::make_shared<std::lock_guard<std::mutex>>(i_mutex);
g(b); // last use of 'b'
i = 5;
}
If b
is moved, this introduces a data race against other threads that synchronize access to i
using i_mutex
.
这篇关于编译器能否自动生成std :: move以自动使用左值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!