Part1はこれ
ものすごくありがたい情報をいただきました。
RVOについて(NRVOというのもある)
これを無効化するオプションがありますよとのこと。
id:yohhoyさんのアドバイスが
gccであれば-fno-elide-constructorsオプションを指定すると、
RVOが無効化されて結果が変わるかと思います。
ということでやってみました。
コードは前回のをちょっと端折ってこれで検証
ソースコード
Part1で書いたものの一部抜粋バージョンです。
フツーにコンパイル
$ g++ -o rvotest.exe rvotest.cpp
実行結果
テスト3_a function test3 called!! mystring constructor mystring(const char *str) called! [test] テスト4_a function test4 called!! mystring constructor mystring(const char *str) called! [test]
おお、ただのコンストラクタしか動いてなくてコピーされていないっぽい!!
RVO/NRVOを無効化してコンパイル(g++)
$ g++ -fno-elide-constructors -o rvotest.exe rvotest.cpp
実行結果
テスト3_a function test3 called!! mystring constructor mystring(const char *str) called! mystring copy constructor mystring(const mystring &rhs) called! mystring copy constructor mystring(const mystring &rhs) called! mystring copy constructor mystring(const mystring &rhs) called! [test] テスト4_a function test4 called!! mystring constructor mystring(const char *str) called! mystring copy constructor mystring(const mystring &rhs) called! mystring copy constructor mystring(const mystring &rhs) called! [test]
はっ!!!!Σ(゚Д゚)なるほど…そういうことだったのですか…
調べたところよっぽど古くないメジャーなコンパイラ(g++とかVC++とか)ならば
基本的にはこのRVO/NRVOが効くようです。
ということで、普通にstd::stringを値で返すようなコードを書いても
遅くならないようになっているようです。
素敵すぎる・・・・・・。
ちなみにテスト3_aで効いているものが
NRVOというものでテスト4_aで効いているものがRVOです。
結論
いまどきのそれなりに古くないコンパイラで
素直にstd::stringを値で返すようなコードを書いてあげてかつ
RVO/NRVOが効きそうなコードを書いてあげれば、
無駄な細工はしなくてよい……。
詳しい方からご教授いただいてとても嬉しいです!ありがとうございました。