Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C++でstd::stringをどう返すべきか Part2

スポンサードリンク

f:id:fa11enprince:20200701030708j:plain
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が効きそうなコードを書いてあげれば、
無駄な細工はしなくてよい……。

詳しい方からご教授いただいてとても嬉しいです!ありがとうございました。