4
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Exmpl{
    Exmpl()
    {
        cout << "Exmpl()" << endl;
    }

    Exmpl(const Exmpl&)
    {
        cout << "Exmpl(const Exmpl&)" << endl;
    }

    Exmpl& operator=(const Exmpl& rhs)
    {
        cout << "operator=Exmpl()" << endl;
        return *this;
    }

    ~Exmpl()
   {
        cout << "~Exmpl()" << endl;
   }
};

void func1(Exmpl obj)
{
}

void func2(Exmpl &obj)
{
}

Exmpl func3()
{
    Exmpl obj;
    return obj;
}

int main()
{
    Exmpl eobj;
    func1(eobj);
    func2(eobj);
    eobj = func3();
    Exmpl *p = new Exmpl;
    vector<Exmpl> evec(3);

    delete p;
    return 0;
}

g ++(4.4.3)でコンパイルすると、

Exmpl()
Exmpl(const Exmpl&)
~Exmpl()
Exmpl()
operator=(const Exmpl&)
~Exmpl()
Exmpl()
Exmpl()
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()

vs2008 では、結果は次のようになります。

Exmpl()
Exmpl(const Exmpl&)
~Exmpl()
Exmpl()
Exmpl(const Exmpl&)
~Exmpl() 
operator=(const Exmpl&)
~Exmpl()
Exmpl()
Exmpl()
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()

コードが「eobj = func3();」になったとき 主に、vs2008 の結果の 5 行目と 6 行目が g++ で見つかりません。いくつかのレベルの最適化を試みましたが、結果は同じです。違いの理由は何ですか?

4

1 に答える 1

8

C++ では、オブジェクトが関数から値として返される場合 ( のようにfunc3())、コピー コンストラクターを省略できます。コンストラクターに新しいオブジェクトの構築以外の副作用がある場合でも、この場合、コピー コンストラクターはcout.

g++最適化が指定されていなくてもそれを行っていますが、MSVC は最適化の実行を要求した場合にのみそれを行います。

プログラムを次のように縮小すると (出力を興味深い部分に切り詰めるために):

int main()
{
    Exmpl eobj;
    eobj = func3();

    return 0;
}

これらのコマンド ラインで生成されたプログラムについては、次のように表示されます (テストは MinGW 4.6.1 および MSVC 16.0、別名 VC++ 2010 で行われました)。

  • g++ -O0 -o test.exe test.cpp(g++、「いいえ」の最適化)
  • g++ -O2 -o test.exe test.cpp(g++、最適化)
  • cl /Ox /EHsc test.cpp (msvc、最適化)

    Exmpl()
    Exmpl()
    operator=Exmpl()
    ~Exmpl()
    ~Exmpl()
    
  • cl /EHsc test.cpp (msvc、最適化なし)

  • g++ -fno-elide-constructors -o test.exe test.cpp (Jesse Good が提案したように、コンストラクターを省略した g++)

    Exmpl()
    Exmpl()
    Exmpl(const Exmpl&)
    ~Exmpl()
    operator=Exmpl()
    ~Exmpl()
    ~Exmpl()
    
于 2012-05-07T05:09:23.500 に答える