Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ code gets different results in g++ and vs2008

Tags:

c++

#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;
}

when compiled in g++(4.4.3) I got

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()

and in vs2008, the result is:

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()

when the code goes to "eobj = func3();" in main, the 5th and 6th lines in vs2008 result can't be found in g++. I've tried to several levels of optimize, but the result is the same. what's the reason of the difference?

like image 829
nzomkxia Avatar asked Feb 21 '23 14:02

nzomkxia


1 Answers

C++ allows copy constructors to be elided when an object is being returned as a value from a function (as in func3()). Even if the constructor has a side effect other than constructing the new object - in this case the copy constructor writes to cout.

g++ is doing that even with no optimization specified, while MSVC will do that only if you ask for optimization to be performed.

If you reduce the program to the following (just to cut the output down to the interesting parts):

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

    return 0;
}

You'll see the following for programs generated with these command lines (tests done with MinGW 4.6.1 and MSVC 16.0, otherwise known as VC++ 2010):

  • g++ -O0 -o test.exe test.cpp (g++, 'no' optimizations)
  • g++ -O2 -o test.exe test.cpp (g++, optimizations)
  • cl /Ox /EHsc test.cpp (msvc, optimziations)

    Exmpl()
    Exmpl()
    operator=Exmpl()
    ~Exmpl()
    ~Exmpl()
    
  • cl /EHsc test.cpp (msvc, no optimizations)

  • g++ -fno-elide-constructors -o test.exe test.cpp (g++ with no constructors elided as suggested by Jesse Good)

    Exmpl()
    Exmpl()
    Exmpl(const Exmpl&)
    ~Exmpl()
    operator=Exmpl()
    ~Exmpl()
    ~Exmpl()
    
like image 119
Michael Burr Avatar answered Mar 08 '23 16:03

Michael Burr