2012-02-03 9 views
1

私は、呼び出し元がすぐに戻り値をコピーすることを意図して、大規模なデータ構造を返す関数があるとします。静的ローカル参照を返す

Large large() 
{ 
    return Large(); 
} 

は、今、私が頼りにしたくないと仮定戻り値の最適化などのコンパイラの最適化の任意の種類。また、私はC + + 11の移動コンストラクタに依存することはできませんと仮定します。私は、次のコードの「正しさ」にいくつかの意見を収集したいと思います:

const Large& large() 
{ 
    static Large large; 
    large = Large(); 
    return large; 
} 

意図したとおりにそれが動作するはずですが、それは資格のconstの場合でも、静的なローカルへの参照を返すために貧しいスタイルですか?

+0

私はあなたが達成しようとしているかどうかはわかりません。あなたが記述した仮説では、最初の方法はまだ正しいです。 –

+0

@Rob最終的には、呼び出し元がメモリ管理を担当することなく、コンパイラについての前提をせずに、参照を返す速度が必要です。 –

+1

その場合、2番目の例は「正しい」ではありません。あなたは 'large()'の中に一つのコピー操作を持っています。私は 'large()'の呼び出し元の中に別のものを想定しています。最適化されていないコンパイラの場合、手で "最適化された"コードは、それが置き換えられるコードより速くはありません。最適化コンパイラの場合は、処理速度が遅くなります。いずれの場合も、維持することはより困難です。 –

答えて

4

これは、すべてのが期待手段として機能すべきかに依存します。この場合、すべての呼び出し元は、まったく同じ変数への参照を共有します。また、発信者がコピーされます場合は、あなたが効果的に [*] は、現在のすべてのコンパイラを働くであろう、RVO(戻り値の最適化)を無効にしていることに注意してください。

私はできるだけ離してそのアプローチからとどまる、それは慣用ではなく、おそらく多くの場合、混乱の原因となります。

[*]私が知っているすべてのコンパイラで呼び出し規約はの(すなわちレジスタに適合しない)変数を返す関数は、呼び出し元が割り当てられている場所に隠されたポインタを受け取ることを決定変数のスペース。つまり、の選択は、呼び出し規約によって強制されます。

3

私はこれを行う上で問題はないと思います。このコードベースがシングルスレッド化されている限り、永遠になるでしょう。

は、コードのマルチスレッドの作品でこれを行うには、あなたのデータはときどきランダムに破壊されている理由を理解することはできませんかもしれません。

関連する問題