Pascal 有個 result 能訪問返回值對象。若函數不是類方法則函數名也可這麼用。

Copy elision - cppreference.com 看這裡的話 C++17 還沒有把 NRVO 強制化,也就是說還不能確保 return 前能構造好返回對象。為何 C 和 C++ 沒有強制在 return 前訪問返回對象的做法,這算不算是設計缺陷?為什麼這麼多年來一直不加上呢?


語言特性層面的返回值優化對 C 程序沒什麼意義,反正 C 也沒有構造函數,直接返回一個局部變數讓編譯器自己優化就行了。

在 C++ 中,強制 NRVO 確實是一個很有用的特性。比如有某個既無法 copy 也無法 move 的類,想要構造一個這個類的對象,在上面進行一些操作,然後再返回。這種時候只能依靠強制 NRVO。

而且強制 NRVO 並非完全不可實現,只需要加上一些限制。比如:

  1. 返回對象必須用特定語法顯式構造。例如 returning Type identifier(args); 這樣。返回對象和其他局部變數一樣擁有自動生存期。
  2. 返回對象析構前必須有一條一定會執行的 return 語句,否則產生編譯期錯誤。當然也可以規定成在返回對象的 scope 結束前自動插入一條 return,除了容易把程序員坑了之外沒什麼毛病。
  3. 在返回對象的生存期內的 return 語句不允許再帶表達式,只能返回該對象。
  4. 在返回對象的生存期內不允許聲明另一個返回對象。

不過說實話,和強制 RVO 比起來,這個設計簡直丑爆了,而且很不 C++。在有大佬想出更優雅的方案之前,強制 NRVO 大概確實沒法進入標準,做成編譯器擴展倒是有可能。


不太明白,如果我要返回一個類,但類需要通過int做參數構造,那麼這個result怎麼初始化?擅作主張拿int的默認值0初始化嗎?

更嚴重一點,萬一這個這個類需要通過某些資源來構造呢,這些資源怎麼來?一點點從根源構造起來?(然後發現有好幾種可行的構造方式)還是說把賦值之前的操作當ub(那還有什麼用)?不太能理解pascal里result的作用,看到似乎還能放在賦值操作右邊當遞歸?
好像一開始pascal沒有return的語句,不知道現在有沒有,估計是沒有的,因為pascal的嚴謹語法,只允許一個函數出口。所以只好用函數名或者result。既然c/c++的return能返回結果,並且功能更加強大,還需要result嗎?後續語言C#和java都一樣沒有result這樣的語法支持


result_t f(bool x) {
// 如果在這裡能訪問返回值變數,那麼在這裡,返回值變數是哪一個,res1 還是 res2
if (x) {
result_t res1;
return res1;
} else {
result_t res2;
return res2;
}
}


其實構造函數不就是這樣。函數內可以直接操作this指針,完全可以把這個this看作是構造函數返回值的地址。(雖然構造函數沒有返回值)


因為C是彙編的高級形式
c++用拷貝構造函數可以在return之前對其訪問

void foo()
{
A a;
return a;
}

像這種情況如果A寫了拷貝構造就會在return之前自動進入拷貝構造函數


有什麼用。。
推薦閱讀:
相关文章