常量右值引用是否允许对编译器进行额外优化?
Does const rvalue references allow extra optimisations for compiler?
C++中函数参数的const
修饰符表示此函数不能更改参数值,但不保证在函数执行期间不能被其他人更改。因此,编译器无法根据数据不变性进行任何优化。
据我了解,右值引用意味着给定的对象是临时的,因此没有其他人可以访问其数据。在这种情况下,编译器可以进行积极的优化吗?
它将允许通过某种
template<class T>
class Immutable
{
private:
const T val;
public:
operator const T && () { return std::move(val); }
};
(只是示例代码),或者在我们确定在函数调用期间无法更改值时按const&&
传递值。有可能吗,或者有一些未提及的问题?
tl'dr:它不启用任何优化,因为它不能以任何方式保证对象不会被修改。它只会增加混乱。不要使用它!
首先,我们需要澄清"被别人改变"是什么意思。
-
通过另一个线程。在这种情况下,您的问题不适用。您需要使用
mutex
或其他机制保护您的数据。否则,编译器可以假定没有其他线程修改数据。 -
同一线程,在函数未(直接或间接)调用的代码中。不可能。
-
同一线程,在函数(直接或间接)调用的代码中。
我们显然会处理最后一个:
让我们看一个简单的代码,看看程序集(-O3
)
auto foo(int& a)
{
a = 24;
return a;
}
foo(int&): # @foo(int&)
mov dword ptr [rdi], 24
mov eax, 24
ret
如您所见mov eax, 24
.返回值设置为24
。这意味着编译器可以假定没有其他代码可以修改a
引用的对象(即使a
是非 const 引用)。
让我们在返回之前添加一个函数调用代码:
auto bar() -> void;
auto foo(int& a)
{
a = 24;
bar();
return a;
}
foo(int&): # @foo(int&)
push rbx
mov rbx, rdi
mov dword ptr [rbx], 24
call bar()
mov eax, dword ptr [rbx]
pop rbx
ret
编译器无法访问bar
正文,因此必须考虑到bar
可以修改a
引用的对象。
现在,根据您的问题将const&
添加到等式中不会改变等式。该对象只能通过在当前函数中调用的代码进行修改。
拥有const&&
不会以任何方式改变这一点。a
引用的对象仍然可以修改。
据我了解,右值引用意味着给定的对象是临时的, 因此没有其他人可以访问其数据
不对。右值引用可以绑定到prvalues
(临时)或xvalues
。您自己的示例显示了这一点:
operator const T && () { return std::move(val); }
在这里,您绑定到val
它不是临时的(如果封闭对象不是)。
乔纳森·韦克利(Jonathan Wakely)在评论中指出:
你的例子证明 const T&& 不必绑定到 临时的,并且可能有多个绑定到 同样的事情:
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));
}
test(): # @test()
mov dword ptr [rip + g], 11
mov eax, 11
ret
上面的代码有效1),它表明const int&&
参数a
引用的对象在调用foo
期间被修改。
1)虽然我不是100%确定,但我相当确定
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- C++编译器是否优化了顺序静态变量读取?
- VS2017调试器:没有地址,可能是由于编译器优化
- 何时允许编译器优化复制构造函数
- 编译器(Visual C++)如何优化按索引访问矢量元素?
- static_assert有助于优化编译器吗?
- 哪个优化编译器开关使调试非常困难
- 优化编译器可以添加std::move吗
- VisualStudio 优化编译器版本 19.00.23506.0 中存在明显的编译错误
- C++是否允许优化编译器忽略对 for 条件的副作用
- 优化编译器能否从 std::unique_ptr 中消除所有运行时成本
- Microsoft c++优化编译器不断崩溃
- 优化编译器如何决定何时展开循环以及展开多少循环
- 有一个很好的测试c++优化编译器
- Mac上的g++链接时间优化-编译器/链接器错误
- visual_itoa_s一直在杀死c++优化编译器,为什么?
- Microsoft C/C++ 优化编译器编译到什么
- 优化编译器消除bug