aaa*_*x88 0 c++ optimization constants compiler-optimization rvalue-reference
constC++中函数参数的修饰符表示该函数不能改变参数值,但不保证在函数执行过程中不能被其他人改变。因此,编译器无法根据数据不变性进行任何优化。
据我了解,右值引用意味着给定的对象是临时的,因此其他人都无法访问其 data。在这种情况下,编译器可以进行积极的优化吗?
它将允许通过某种方式获得更快的代码
template<class T>
class Immutable
{
private:
const T val;
public:
operator const T && () { return std::move(val); }
};
Run Code Online (Sandbox Code Playgroud)
(只是示例代码),或者const&&当我们确定它们在函数调用期间无法更改时传递值。是否有可能,或者有一些未提及的问题?
tl'dr:它不启用任何优化,因为它不以任何方式保证对象不被修改。它只会增加混乱。不要使用它!
首先我们需要弄清楚“被别人改变”是什么意思。
通过另一个线程。在这种情况下,您的问题不适用。您需要使用一种mutex或其他机制来保护您的数据。否则编译器可以假设没有其他线程修改数据。
同一线程,在函数未调用(直接或间接)的代码中。不可能。
同一线程,在函数调用(直接或间接)的代码中。
我们显然会处理最后一个:
让我们看一个简单的代码,看看程序集(-O3)
auto foo(int& a)
{
a = 24;
return a;
}
Run Code Online (Sandbox Code Playgroud)
foo(int&): # @foo(int&)
mov dword ptr [rdi], 24
mov eax, 24
ret
Run Code Online (Sandbox Code Playgroud)
正如你所看到的mov eax, 24。返回值设置为24。这意味着编译器可以假设没有其他代码可以修改所引用的对象a(即使a是非常量引用)。
让我们在返回之前添加一个函数调用代码:
auto bar() -> void;
auto foo(int& a)
{
a = 24;
bar();
return a;
}
Run Code Online (Sandbox Code Playgroud)
foo(int&): # @foo(int&)
push rbx
mov rbx, rdi
mov dword ptr [rbx], 24
call bar()
mov eax, dword ptr [rbx]
pop rbx
ret
Run Code Online (Sandbox Code Playgroud)
编译器无权访问 的主体,bar因此它必须考虑bar可能会修改a.
现在const&根据您的问题添加到等式中不会改变等式。该对象只能通过在当前函数中调用的代码进行修改。
拥有const&&不会以任何方式改变这一点。引用的对象a仍然可以修改。
据我了解,右值引用意味着给定的对象是临时的,所以其他人都无法访问其数据
不对。右值引用可以绑定到prvalues(temporaries) 或xvalues. 您自己的示例显示了这一点:
operator const T && () { return std::move(val); }
Run Code Online (Sandbox Code Playgroud)
在这里你绑定到val哪个不是临时的(如果封闭对象不是)。
乔纳森·韦克利 (Jonathan Wakely) 在评论中指出:
您的示例证明 const T&& 不必绑定到临时对象,并且可能有多个右值引用绑定到同一事物:
Run Code Online (Sandbox Code Playgroud)Immutable<int> i{}; const int&& r1 = i; const int&& r2 = i;所以这与
const&情况没有什么不同
这是我的看法:
int g = 24;
auto bar() -> void { g = 11; };
auto foo(const int&& a)
{
bar();
return a;
}
auto test()
{
return foo(std::move(g));
}
Run Code Online (Sandbox Code Playgroud)
test(): # @test()
mov dword ptr [rip + g], 11
mov eax, 11
ret
Run Code Online (Sandbox Code Playgroud)
上面的代码是有效的1)说明const int&&参数a所引用的对象在调用foo.
1)虽然我不是 100% 确定,但我相当确定