如何强制rvalue引用为“限制”别名?

时间:2017-02-08 13:09:50

标签: c++ move-semantics rvalue-reference strict-aliasing

在C ++标准(N4618,$ 17.5.4.9,[res.on.argument],(1.3))中,可以说实现是免费的,不对rvalue引用执行别名检查:

  

如果函数参数绑定到右值引用参数,则实现可以假设   此参数是对此参数的唯一引用。 [   注意:   如果参数是通用参数   形式   T&安培;&安培;   和一个类型的左值   一个   绑定,参数绑定到左值引用(14.8.2.1)   因此不在前一句中。    - 结束说明   ] [[   注意:   如果程序转换左值   将该左值传递给库函数时的xvalue(例如,通过使用参数调用该函数)   的std ::移动(X)   ),该程序有效地要求该函数将该左值作为临时值处理。   实现可以自由地优化别名检查,如果参数可能需要这些检查   是一个左值。    - 结束说明   ]

我希望将这样的假设应用于整个翻译单元。例如,函数f

 class A{
    int a;
      //....
 };
 int f(A&& r1,A&& r2){
   r1.a=10;
   r2.a=3;
   return r1.a;
 }

生成以下程序集:

    movl    $10, (%rdi)
    movl    $3, (%rsi)
    movl    (%rdi), %eax
    retq

如果返回值是r1.a的加载,因为编译器会考虑f可能以这种方式调用:f(move(an_A),move(an_A))

现在,如果我将其中一个参数声明为限制:

int f(A&& __restrict__ r1,A&& r2){
   r1.a=10;
   r2.a=3;
   return r1.a;
 }

我们得到以下程序集:

    movl    $10, (%rdi)
    movl    $3, (%rsi)
    movl    $10, %eax
    retq

在这种情况下,我们告诉编译器假设参数r1r2永远不会绑定到同一个对象。因此它直接返回a.a中存储的值。

对于任何采用右值参考参数的库函数,这正是C ++标准所允许的那种优化。

我相信在大多数(如果不是全部)真实案例程序中,像f(move(an_A),move(an_A))这样的调用肯定会导致“无证件行为”,因为作为程序员,我永远不会指望用户传递两个有效的参数参数同一个对象。

所以我几乎没有问题:

  1. 他们的真实案例是f(move(an_A),move(an_A))这样的调用发生了,所以在实施f时,程序员必须处理这个调用案例吗?
  2. 如果不是,为什么编译器不假设所有右值参考参数都是“受限制的”?
  3. 是否有任何优化选项强制编译器假定所有右值参考参数都是“受限制的”?

0 个答案:

没有答案