常量值引用是否允许对编译器进行额外的优化? const > C++中的函数参数修饰符意味着该函数不能改变参数值,但不能保证函数执行过程中不能由其他人改变。所以,编译器不能依靠数据不变性进行任何优化

常量值引用是否允许对编译器进行额外的优化? const > C++中的函数参数修饰符意味着该函数不能改变参数值,但不能保证函数执行过程中不能由其他人改变。所以,编译器不能依靠数据不变性进行任何优化,c++,optimization,constants,compiler-optimization,rvalue-reference,C++,Optimization,Constants,Compiler Optimization,Rvalue Reference,据我所知,右值引用意味着给定的对象是临时的,因此其他人无权访问其数据。在这种情况下,编译器可以进行积极的优化吗 它将允许通过某种方式获得更快的代码 template<class T> class Immutable { private: const T val; public: operator const T && () { return std::move(val); } }; 模板 类不可变 { 私人: const T val;

据我所知,右值引用意味着给定的对象是临时的,因此其他人无权访问其数据。在这种情况下,编译器可以进行积极的优化吗

它将允许通过某种方式获得更快的代码

template<class T>
class Immutable 
{ 
private: 
    const T val; 
public: 
    operator const T && () { return std::move(val); } 
};
模板
类不可变
{ 
私人:
const T val;
公众:
运算符const&({return std::move(val);}
};

(仅示例代码),或者在我们确定不能在函数调用期间更改值时,通过
const&&
传递值。是否可能,或者存在一些未提及的问题?

tl'dr:它无法启用任何优化,因为它无法以任何方式保证对象未被修改。这只会增加混乱不要使用它


首先,我们需要澄清“被其他人改变”的含义

  • 另一条线索。在这种情况下,你的问题不适用。您需要使用
    互斥锁
    或其他机制来保护数据。否则,编译器可以假定没有其他线程修改数据

  • 相同的线程,在一个未被函数(直接或间接)调用的代码中。不可能

  • 相同的线程,在函数(直接或间接)调用的代码中

我们显然将处理最后一个问题:


让我们看一段简单的代码,看看程序集(
-O3

如您所见,mov eax,24。返回值设置为
24
。这意味着编译器可以假设没有其他代码可以修改
a
引用的对象(即使
a
是非常量引用)

让我们在返回之前添加函数调用代码:

auto bar() -> void;

auto foo(int& a)
{
  a = 24;
  bar();
  return a;
}
编译器没有访问
bar
主体的权限,因此必须考虑
bar
可以修改
a
引用的对象

现在,根据您的问题将
const&
添加到等式中不会改变等式。只能通过在当前函数中调用的代码修改对象

拥有
const&
不会以任何方式改变这一点。
a
引用的对象仍然可以修改

据我所知,右值引用意味着给定的对象是临时的, 所以没有其他人可以访问它的数据

不是真的。右值引用可以绑定到
prvalues
(临时值)或
xvalues
。您自己的示例显示了这一点:

operator const T && () { return std::move(val); } 
这里您绑定到
val
,它不是临时对象(如果封闭对象不是临时对象)

乔纳森在一篇评论中明确指出:

您的示例证明,const T&&不必绑定到 临时的,并且可能有多个绑定到 同样的事情:

Immutable<int> i{};
const int&& r1 = i;
const int&& r2 = i;
上面的代码是有效的1),它表明
const int&
参数
a
引用的对象在调用
foo
期间被修改


1) 虽然我不是100%确定,但我相当确定:它不能启用任何优化,因为它不能以任何方式保证对象不被修改。这只会增加混乱不要使用它


首先,我们需要澄清“被其他人改变”的含义

  • 另一条线索。在这种情况下,你的问题不适用。您需要使用
    互斥锁
    或其他机制来保护数据。否则,编译器可以假定没有其他线程修改数据

  • 相同的线程,在一个未被函数(直接或间接)调用的代码中。不可能

  • 相同的线程,在函数(直接或间接)调用的代码中

我们显然将处理最后一个问题:


让我们看一段简单的代码,看看程序集(
-O3

如您所见,mov eax,24。返回值设置为
24
。这意味着编译器可以假设没有其他代码可以修改
a
引用的对象(即使
a
是非常量引用)

让我们在返回之前添加函数调用代码:

auto bar() -> void;

auto foo(int& a)
{
  a = 24;
  bar();
  return a;
}
编译器没有访问
bar
主体的权限,因此必须考虑
bar
可以修改
a
引用的对象

现在,根据您的问题将
const&
添加到等式中不会改变等式。只能通过在当前函数中调用的代码修改对象

拥有
const&
不会以任何方式改变这一点。
a
引用的对象仍然可以修改

据我所知,右值引用意味着给定的对象是临时的, 所以没有其他人可以访问它的数据

不是真的。右值引用可以绑定到
prvalues
(临时值)或
xvalues
。您自己的示例显示了这一点:

operator const T && () { return std::move(val); } 
这里您绑定到
val
,它不是临时对象(如果封闭对象不是临时对象)

乔纳森在一篇评论中明确指出:

您的示例证明,const T&&不必绑定到 临时的,并且可能有多个绑定到 同样的事情:

Immutable<int> i{};
const int&& r1 = i;
const int&& r2 = i;
上面的代码是有效的1),它表明
const int&
参数
a
引用的对象在调用
foo
期间被修改


1) 虽然我不是100%确定,但我相当肯定“被其他人更改”的定义,它的意思是通过其他对象中的非常量引用进行更改。参见我的答案。这有不同的场景。O
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