7

テスト環境: vs 2008、デバッグモード

テストコードは次のとおりです。

// a demo for return value

class C
{
public:
    int value;
    int value2;
    int value3;

    //C(int v=0): value(v) {};
};

C getC(int v)
{
    C c1;

    return c1;
}



int main()
{
    C c1 = getC(10);

    return 0;
}

asm の出力は次のとおりです。

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR $T2595[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8
mov ecx, DWORD PTR [eax]
mov DWORD PTR $T2594[ebp], ecx
mov edx, DWORD PTR [eax+4]
mov DWORD PTR $T2594[ebp+4], edx
mov eax, DWORD PTR [eax+8]
mov DWORD PTR $T2594[ebp+8], eax
mov ecx, DWORD PTR $T2594[ebp]
mov DWORD PTR _c1$[ebp], ecx
mov edx, DWORD PTR $T2594[ebp+4]
mov DWORD PTR _c1$[ebp+4], edx
mov eax, DWORD PTR $T2594[ebp+8]
mov DWORD PTR _c1$[ebp+8], eax

asm の出力から、コンパイルによって 2 つの一時オブジェクトが作成されていることがわかります。

ただし、コンストラクターを次のように定義すると、次のようになります。

C(int v=0): value(v) {};

プログラムを再コンパイルすると、asm 出力は次のようになります。

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR _c1$[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8

明らかに、コンパイラはコードを最適化します。私の質問は次のとおりです。

ユーザー作成のコンストラクターを追加すると、生成されたアセンブリに大きな影響を与えるのはなぜですか?

4

1 に答える 1

1

この質問は、C++ でのコピー省略と戻り値の最適化に関するものです。

生成されるアセンブリ コードはコンパイラに依存するため、あまり時間をかけないことをお勧めします。

コピー省略は標準で定義されています。

特定の基準が満たされている場合、オブジェクトのコピー/移動コンストラクターおよび/またはデストラクタに副作用がある場合でも、実装はクラス オブジェクトのコピー/移動構築を省略できます。このような場合、実装は、省略されたコピー/移動操作のソースとターゲットを、同じオブジェクトを参照する 2 つの異なる方法として扱い、そのオブジェクトの破棄は、2 つのオブジェクトが削除された時点のいずれか遅い方の時点で発生します。最適化なしで破壊されました。コピー省略と呼ばれるこのコピー/移動操作の省略は、次の状況で許可されます (複数のコピーを排除するために組み合わせることができます)。

[...]

§12.8 [class.copy]

stackoverflow で参照できる質問が既にあります。ここを参照してください。

于 2014-08-15T03:58:03.767 に答える