6

VS 2010 を完全最適化 /Ox で使用して、次の 2 つの関数呼び出しを確認します。

static string test1(const string& input)
{
    return input;
}

static void test2(const string& input, string& output)
{
    output = input;
}

後者の test2 を使用すると、関数は常に最適化され、コードはインライン化されます。ただし、例外をオフにしない限り、test1 はインライン化されません。これがなぜなのか誰か知っていますか?

さらに、戻り値の最適化を使用している場合、コンパイラは test1 で test2 として効率的なジョブとして実行できると期待していますが、それを行っていないようです。これもまた、私を不可解にしています。

最初の関数シグネチャを使用する理由は、関数のコンパイル可能なバージョンが 2 つあるためです。呼び出し元のコードで常に test1 を呼び出すようにし、特定のコンパイル フラグが設定されている場合は入力をコピーに追加して返し、コンパイル フラグが設定されていない場合は no に近づけたい- 可能な限り。

4

2 に答える 2

8

Visual Studio は、自明でないデストラクタを持つオブジェクトを返す関数をインライン化できません。

場合によっては、機械的な理由でコンパイラが特定の関数をインライン化しないことがあります。たとえば、コンパイラはインライン化しません。
  • SEH と C++ EH の両方が混在する場合の関数。
  • -GX/EHs/EHa がオンの場合、値によって渡されるコピー構築オブジェクトを持つ一部の関数。
  • -GX/EHs/EHa がオンの場合、巻き戻し可能なオブジェクトを値で返す関数。
  • -Og/Ox/O1/O2 なしでコンパイルすると、インライン アセンブリで機能します。
  • 可変引数リストを持つ関数。
  • try (C++ 例外処理) ステートメントを含む関数。

http://msdn.microsoft.com/en-us/library/a98sb923.aspx

于 2012-04-09T01:19:18.597 に答える
2

標準では、戻り値が関数のパラメーターである場合、コンパイラが戻り値の最適化を使用することを明示的に禁止しています (12.8/31)。

コピー省略と呼ばれるこのコピー/移動操作の省略は、次の状況で許可されます (複数のコピーを排除するために組み合わせることができます)。

— クラスの戻り値の型を持つ関数の return ステートメントで、式が関数の戻り値の型と同じ cv 非修飾型を持つ非揮発性自動オブジェクト (関数または catch-clause パラメーター以外) の名前である場合、自動オブジェクトを関数の戻り値に直接構築することにより、コピー/移動操作を省略できます

— ...

于 2012-04-09T07:34:34.780 に答える