1

const C++中函數參數的修飾符意味着此函數不能更改參數值,但不能保證函數在執行過程中不能被其他人更改。所以,編譯器不能依賴數據不可變性進行任何優化。const rvalue引用是否允許對編譯器進行額外優化?

據我所知,右值引用意味着給定的對象是暫時的,所以沒有其他人可以訪問其數據。在這種情況下,編譯器可以進行攻擊優化嗎?

這將允許通過某種

template<class T> 
class Immutable 
{ 
private: 
    const T val; 
public: 
    operator const T &&() { return std::move(val); } 
}; 

(只是示例代碼)有更快的代碼,或者通過const&&傳遞值時,我們肯定不能被函數調用過程中改變。這是可能的,還是有一些未提及的問題?

+1

限定 – bolov

+0

這意味着在一些其他對象非const引用改變「別人改變。」 – aaalex88

+0

看到我的答案。這有不同的場景。一個是「被另一個線程修改」,另一個是「被相同線程修改」 – bolov

回答

4

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你是不是臨時的(如果封裝的對象不是)。

喬納森Wakely釘它在一篇評論:

你舉的例子證明,常量牛逼& &不必綁定到一個 暫時的,有可能是綁定到 相同的幾個右值引用事情:

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%肯定,我相當肯定

+0

因此,由其他ref訪問右值引用不是UB的標準?這是可悲的。 – aaalex88

+0

@ aaalex88它與const&'如何工作是一致的 – bolov

相關問題