Re: [問題] return a local value

看板C_and_CPP作者 (-858993460)時間14年前 (2011/12/24 18:06), 編輯推噓3(3034)
留言37則, 5人參與, 最新討論串2/2 (看更多)
※ 引述《rnbjacky (你今天浪費時間了嗎?)》之銘言: : 問題(Question): : 請問第30行 " return obj; " 回傳local variable 值到main時 : 做了什麼事? copy ctor? : 可以讓main好像有了一個新的物件,不會因為out of scope結果輸出錯誤值 : 感謝!! : 程式碼(Code):(請善用置底文網頁, 記得排版) : http://codepad.org/7SnYOmdn 正常來說你的猜測是對的 在回傳一個物件 A 時通常會用 copy constructor 複製一份成 A' 傳出來 不過你這裡的情形正好可以啟動一個稱做 RVO 的最佳化策略 RVO 全名 return value optimization 當回傳的物件是拿來給另一個物件 B 初始化時 例如像你 36 行這樣寫的時候 RVO 可以讓函式裡面對那個物件做事直接等於在外面的物件 B 上做事 這樣可以省去兩個 copy constructor 的呼叫 (一個是 A 複製成 A' 另一個是 A' 複製成 B) 那麼當 RVO 有被啟動時 str() 裡的 obj 的位址就會和 main 裡的 y 的位址相同 這就是代表 y 的位址其實被偷偷傳進去 當成 str() 裡 obj 的位址了 注意到如果你的 36 行 如果宣告和指定值分開了 像是寫成 Str y; y = str(); 這樣由於前面的 Str y; 表示到那裡一個 y 要完全建構 後面的 y = str(); 就不得不使用 operator = 來指定值 這樣一來 RVO 不會啟動 裡面的 obj 就和外面的 y 是不同的兩個物件 -- 1985/01/12 三嶋鳴海 1989/02/22 優希堂悟 1990/02/22 冬川こころ 1993/07/05 小町 つぐみ 歡迎來到 1994/05/21 高江ミュウ 1997/03/24 守野いづみ 1997/03/24 伊野瀬 チサト 1998/06/18 守野くるみ 打越鋼太郎的 1999/10/19 楠田ゆに 2000/02/15 樋口遙 2002/12/17 八神ココ 2011/01/11 HAL18於朱倉岳墜機 ∞與∫的世界 2011/04/02 茜崎空 啟動 2012/05/21 第貮日蝕計畫預定 2017/05/01~07 LeMU崩壞 2019/04/01~07 某大學合宿 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.28.91

12/24 18:10, , 1F
稍微看了一下前面的 RVO 的那三篇文
12/24 18:10, 1F

12/24 18:11, , 2F
我這裡似乎是把兩種 RVO 混在一起講了
12/24 18:11, 2F

12/24 18:11, , 3F
這就有請更了解它們的人來說吧...
12/24 18:11, 3F

12/24 19:52, , 4F
他的strPtr也有問題吧?
12/24 19:52, 4F

12/24 20:10, , 5F
另外既然有RVO了,怎麼obj與obj_main兩個addr不同?
12/24 20:10, 5F

12/24 20:47, , 6F
樓上: 因為codepad編譯的時候加入了-fno-elide-constructors
12/24 20:47, 6F

12/24 21:12, , 7F
樓上:抱歉不太懂你的意思,不過我編譯是自己用gcc
12/24 21:12, 7F

12/24 21:21, , 8F
不好意思 我以為你是直接看codepad上面輸出的結果
12/24 21:21, 8F

12/24 21:22, , 9F
你可以講一下你的gcc版本和編譯用的參數嗎
12/24 21:22, 9F

12/24 21:23, , 10F
如果我沒記錯的話 gcc預設是會啟動RVO的
12/24 21:23, 10F

12/24 21:34, , 11F
大大們 我用vc++ 和 codeBlock 兩個編譯後執行結果 :
12/24 21:34, 11F

12/24 21:34, , 12F
obj和 obj_main 的位址是不一樣的 , 這樣是沒啟動RVO嗎?
12/24 21:34, 12F

12/24 21:56, , 13F
剛剛會不同是用cb編譯的,直接下g++ -o這樣就是一樣
12/24 21:56, 13F

12/24 21:56, , 14F
難道是cb預設不用RVO?
12/24 21:56, 14F

12/24 21:57, , 15F
另外想請問為何obj與obj_main兩個addr不同?
12/24 21:57, 15F

12/24 22:13, , 16F
mingw32-g++.exe -fexceptions -pedantic-errors
12/24 22:13, 16F

12/24 22:13, , 17F
-std=c++0x -Wfatal-errors -Wextra -Wall -g
12/24 22:13, 17F

12/24 22:13, , 18F
我看cb有這些參數
12/24 22:13, 18F

12/24 22:21, , 19F
標準沒有說要傳 y 的位置進去吧...搞不好實作用 inline xD
12/24 22:21, 19F

12/24 22:30, , 20F
抱歉上面在推的問題耍笨了,想問的是strPtr好像怪怪
12/24 22:30, 20F

12/24 22:30, , 21F
他指向一個local value?
12/24 22:30, 21F

12/24 22:31, , 22F
另外直接下g++ -o也是不一樣的位址...
12/24 22:31, 22F

12/24 22:32, , 23F
抱歉一直推文= =都推錯
12/24 22:32, 23F

12/24 22:41, , 24F
我覺得是mingw-gcc的implementation quality的問題
12/24 22:41, 24F

12/24 22:43, , 25F
上述例子linux底下gcc是會做rvo的 但是mingw-gcc不會
12/24 22:43, 25F

12/24 22:43, , 26F
但是如果自己寫一個copy ctor mingw-gcc就會做rvo了...
12/24 22:43, 26F

12/24 22:51, , 27F
另外msvc預設是不會做nrvo的 請記得開optimization XD
12/24 22:51, 27F

12/24 22:51, , 28F
我寫一個空的copy,addr就都一樣了,這樣strPtr就是
12/24 22:51, 28F

12/24 22:51, , 29F
正常的了,這樣應該就是表示RVO有用到了吧
12/24 22:51, 29F

12/24 22:55, , 30F
基本上第40行*strPtr的用法是十分危險的 它只向一個已經超出
12/24 22:55, 30F

12/24 22:55, , 31F
scope的local變數 沒炸掉是幸運剛好compiler有做NRVO XD
12/24 22:55, 31F

12/24 23:05, , 32F
確實,所以剛剛沒有RVO我一直覺得很怪...
12/24 23:05, 32F

12/25 00:07, , 33F
我會設那個指標 只是想抓local的位址來看和main的一不一
12/25 00:07, 33F

12/25 00:08, , 34F
樣而已 不是要拿來取local的值
12/25 00:08, 34F

12/25 00:11, , 35F
不要用指標直接show也可以啊...
12/25 00:11, 35F

12/25 02:01, , 36F
哦 因為我想在main裡面看 是不是有out of scope
12/25 02:01, 36F

12/25 02:01, , 37F
     還想
12/25 02:01, 37F
文章代碼(AID): #1EzQGa-F (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1EzQGa-F (C_and_CPP)