関数の返り値の有効範囲はどこまでなのでしょうか?
まず、この疑問は次の仮定が誤っていないことを前提としています。
仮定:
ポインタや参照ではなく実体を返す関数が返値を返すと、その分のメモリ領域が確保され、一旦そこにデータが保存される
単純に考えると、 } まででしょうか?
それとも、その行の終わりまで来ると消滅してしまうのでしょうか。
はたまた、それを関数の引数に渡した場合は・・・?
ご教授よろしくお願いいたします。
関数の返値の有効範囲について
Re: 関数の返値の有効範囲について
どういうコードを想定されていますか?MoNoQLoREATOR さんが書きました: 単純に考えると、 } まででしょうか?
どういうコードを想定されていますか?MoNoQLoREATOR さんが書きました: それとも、その行の終わりまで来ると消滅してしまうのでしょうか。
どういうコードを想定されていますか?MoNoQLoREATOR さんが書きました: はたまた、それを関数の引数に渡した場合は・・・?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 関数の返値の有効範囲について
具体例を書いてみていただけないでしょうか。beatle さんが書きました:その文の終わりまで、だったと思います。
「その文」というのが何を指すのか、今ひとつピンと来ないものでして。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 関数の返値の有効範囲について
『一時オブジェクト』を調べてみてください。
一時オブジェクトの生存期間は完結式の終わりまでです。
いくつか例外がありますが関数の戻り値はそこに含まれません。
一時オブジェクトの生存期間は完結式の終わりまでです。
いくつか例外がありますが関数の戻り値はそこに含まれません。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: 関数の返値の有効範囲について
#include <string>
string getstr(){
string output;
return output;
}
int main(){
const char *str = getstr().c_str();
printf(str);
}
string型で拾って内容をコピーさせるしかなさそうですね。
ありがとうございました。
Re: 関数の返値の有効範囲について
仮にstringで拾ったとしても、文字列の内容がコピーされることはないのではないかと思います。
string内部には普通参照カウントがありますので、(そして一時オブジェクトが破棄される前に変更されることもないので)
コピーは浅く行われると予想できます。(予想ですが・・・)
ということでオーバーヘッドは大したことないのではないかと。
追記:
確かにこの場合はNRVOが適応されますね。失礼しました。
自分の話は仮に関数がもっと複雑で、複数のreturn文で異なる名前のインスタンスを返したとしてもと受け取ってください・・・。
string内部には普通参照カウントがありますので、(そして一時オブジェクトが破棄される前に変更されることもないので)
コピーは浅く行われると予想できます。(予想ですが・・・)
ということでオーバーヘッドは大したことないのではないかと。
追記:
確かにこの場合はNRVOが適応されますね。失礼しました。
自分の話は仮に関数がもっと複雑で、複数のreturn文で異なる名前のインスタンスを返したとしてもと受け取ってください・・・。
最後に編集したユーザー GRAM on 2011年11月10日(木) 01:55 [ 編集 1 回目 ]
- tk-xleader
- 記事: 158
- 登録日時: 13年前
- 連絡を取る:
Re: 関数の返値の有効範囲について
「NRVO」や「戻り値最適化」あたりで検索してもらえればより分かりやすい情報が得られると思いますが…
getstr 関数の戻り値はどうせ捨てられる値なので、コピーするよりもムーブしたほうが無駄がありません。C++03でも、この最適化は行われます。
ですから、コピーのコストについては、そこまで問題ではないかと思います。
getstr 関数の戻り値はどうせ捨てられる値なので、コピーするよりもムーブしたほうが無駄がありません。C++03でも、この最適化は行われます。
ですから、コピーのコストについては、そこまで問題ではないかと思います。
Re: 関数の返値の有効範囲について
C++11ではstd::basic_stringを参照カウントで実装するのは禁止(というより実質的に不可能)になりました。GRAM さんが書きました:仮にstringで拾ったとしても、文字列の内容がコピーされることはないのではないかと思います。
string内部には普通参照カウントがありますので、(そして一時オブジェクトが破棄される前に変更されることもないので)
コピーは浅く行われると予想できます。(予想ですが・・・)
ということでオーバーヘッドは大したことないのではないかと。
Re: 関数の返値の有効範囲について
僕も少し勘違いしていました。ISLeさんのいうとおり、完結式(full-expression)の終わりまで、のようですね。box さんが書きました:具体例を書いてみていただけないでしょうか。beatle さんが書きました:その文の終わりまで、だったと思います。
「その文」というのが何を指すのか、今ひとつピンと来ないものでして。
ちなみに、「その文」というのは、関数呼び出しを含む文、という意味で使いました。
以下、規格などを調べつつ書いてみました。
式1は他の式の部分式ではないため完結式です。
したがって、strへの代入が終了した時点で完結式が終わり、getstr()の戻り値(一時オブジェクト)のデストラクタが呼ばれます。
もちろんprintf(str)は不正なアクセスです。
一方で の場合、式2は「式3, 式4」という形になっています。
一時オブジェクトを生成する式3は式2の部分式ですから完結式ではなく、式2が完結式です。
カンマ演算子で繋がれた式は左から右に評価されますから、式4が終了すれば式2が終了します。
したがって、式4、つまりprintf(str)を実行後、getstr()の戻り値(一時オブジェクト)のデストラクタが呼ばれます。
printf(str)は不正なアクセスにはなりません。