编译器能否自动生成std :: move以自动使用左值? [英] Can compiler generate std::move for a last use of lvalue automatically?

查看:56
本文介绍了编译器能否自动生成std :: move以自动使用左值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆