3

別の関数からの結果をチェックし、特定の基準を満たしている場合に渡す目的でのみ使用されるローカルがあります。ほとんどの場合、その基準が満たされることはありません。この「余分な」ローカルを回避する方法はありますか?

バイナリ用に約 1MB のストレージしかなく、このパターンに従う数千の関数呼び出しがあります。些細なことだとは思いますが、もっと良いパターンがあれば知りたいです!

SomeDataType myclass::myFunction()
{
   SomeDataType result;  // do I really need this local???

   // i need to check the result and pass it on if it meets a certain condition
   result = doSomething();
   if ( ! result ) {
      return result;
   }

   // do other things here
   ...

   // normal result of processing
   return SomeDataType(whatever);
}
4

10 に答える 10

4

はどのくらい複雑ですSomeDataTypeか? 会員数は多いですか?コンストラクターで多くの作業を行いますか? もしそうなら、私はこれを避けます。そうでない場合は、コンパイラがこれに適したコードを生成することがあります。たとえば、コンパイラはおそらく整数型をうまく処理します。

このような質問の場合、ほとんどの場合、答えは次のとおりです。コンパイラのアセンブリ出力を参照してください。

于 2010-03-04T09:01:16.090 に答える
1

関数の他の場所で結果変数を使用していない場合は、これを試すことができます。

if (!doSomething())
{
    return;
}

上記の例では、コンパイラに一時変数を作成するように指示するのではなく、必要に応じてコンパイラが一時変数を作成できるようにします。

あなたが構造化プログラミングにこだわるなら、これを試すことができます:

do
{
    if (!doSomething())
    {
        break;
    }
// ...
} while (false);
return;

この例では、関数内で 1 つのリターン ポイントのみを使用できます。品質とトレーサビリティのガイドラインを扱う場合、これは良いことかもしれません.

于 2010-03-04T17:54:17.317 に答える
1

コードを逆アセンブルして、コードを生成するときにコンパイラが何をしているかを把握します。最近のコンパイラはいくつかのトリッキーなことを行っており、コード スペースを節約する方法を推測しようとしても明らかではありません。ソースからアセンブリへの対応がほとんど見られないことがあります。ソース コードは、明快さとメンテナンスに重点を置いています。アセンブリの生成にはさまざまな指標があります。

于 2010-03-15T14:53:50.237 に答える
1

コンパイラに戻り値の最適化があるかどうか、および Somedatatype が大きいか小さいかによって異なります。オブジェクトが大きい場合、この種のパターンにはスマート ポインターを使用するのが安全な方法です。それらが POD の場合、最適化されてレジスターに返される可能性があります。

于 2010-03-04T09:10:31.157 に答える
1

関数を次のように変更するとどうなりますか

void myclass::myFunction(SomeDataType* pResult)
{
  // i need to check the result and pass it on if it meets a certain condition
   *pResult = doSomething();
   if ( ! *pResult ) {
      return;
   }

   // do other things here
   ...

   // normal result of processing
  *pResult = SomeDataType(whatever);
}
于 2010-03-04T09:25:36.797 に答える
0

何千もの関数で繰り返されるパターンがある場合は、それを 1 つの関数とルックアップ テーブルに置き換えることを検討できます。

(あなたの状況についての詳細を知らなければ、私は本当により具体的には言えません。)

于 2010-03-09T04:25:47.480 に答える
0

コンパイラ オプションを確認し、「サイズを最適化する」ように設定されていることを確認することをお勧めします。また、コンパイラにこのような設定がない場合は、おそらく別の設定を確認するときです。

于 2010-03-17T02:35:49.153 に答える
0

doSomething() の呼び出しでは、null を返す代わりに、SomeDataType(何でも) を返すことができます。

于 2010-04-21T18:36:14.120 に答える
0

asveikau が指摘したように、SomeDataType が「レジスタに収まる」場合 (つまり、プレーンな古い int)、ローカルは (プラットフォームに応じて) メモリを無駄にしません。そして、これが当てはまるかどうかを評価するには、アセンブリ出力を参照する必要があるという asveikau に同意します。

于 2010-03-04T09:07:05.907 に答える
0

気にしないことをお勧めします。まともなコンパイラは必要なローカルストレージの量を最小限に抑えるため、このレベルで最適化するのは時間の無駄遣いです。スタックは再利用可能です。メモリはそれが使用されるコンテキストにのみ必要であり、それ以上は関係ないため、何千回もの呼び出しは問題になりません。

スタック上の数バイトの一時ストレージを気にする必要がある場合は、おそらくアセンブリで作業する必要があります。私はこれが事実であるとは思わないので、汗を流さずに、他のもっと興味深く重要な問題に時間を費やしてください!

于 2010-04-28T23:03:51.557 に答える