[英]Why disabling copy elision for std::atomic doesn't work using C++17?
對於std::atomic
復制構造函數被刪除,並且由於復制省略,這應該只用 C++17 和更高版本編譯:
std::atomic<int> t_int = 1;
我預計它不會使用-fno-elide-constructors
標志進行編譯,但它仍然可以編譯:
https://godbolt.org/z/nMvG5vTrK
為什么是這樣?
C++17 並不僅僅說以前可選的返回值優化現在是強制性的。 語言的實際描述發生了變化,因此一開始就不再創建臨時的 object。
因此,自 C++17 以來,不再有可以省略的構造函數調用。 因此, -fno-elide-constructors
不添加任何臨時創建是有道理的。 那將違反語言規則。
在 C++17 之前,該語言描述了創建一個臨時變量 object,從中初始化變量,然后添加允許編譯器省略這個臨時變量。 因此,無論是否使用-fno-elide-constructors
,編譯器都會通過省略或不省略臨時副本來表現出符合標准的行為。
我預計它不會使用 -fno-elide-constructors 標志進行編譯,
給定標志對 C++17 及以后的返回值優化(又名 RVO)沒有影響。 這是因為它不再被視為優化(來自 C++17),而是一種語言保證。
來自強制復制 elison :
在以下情況下,編譯器需要省略 class 對象的復制和移動構造,即使復制/移動構造函數和析構函數具有可觀察到的副作用。 對象直接構建到存儲中,否則它們將被復制/移動到. 復制/移動構造函數不需要存在或可訪問:
- 在object 的初始化中,當初始化表達式是與變量類型相同的 class 類型(忽略 cv 限定)的純右值時:
(強調我的)
這意味着t_int
是直接從prvalue
1
構造的。 標志-fno-elide-constructors
對 RVO 沒有影響,這與 NRVO 不同。 因此,被刪除的復制構造函數對您的情況沒有影響。
也許一個例子可能有助於說明相同的,
struct Custom
{
public:
Custom(int p): m_p(p)
{
std::cout<<"converting ctor called"<<std::endl;
}
Custom(const Custom&) = delete; //deleted copy ctor
private:
int m_p = 0;
};
int main()
{
Custom c = 1; //works in C++17 but not in Pre-C++17
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.