Skip to content
Advertisement

What is the cause of the difference in return value between Linux and Windows and how to fix it?

Here is the code that I tried to return an object of a class. but I got different results from CentOs (gcc) and visual studio 2013. In the cls.cpp, with gcc, it works well, I get the results such as detector.name = “t_name”, detector.stride = 5. but the values in the detector are “” and 0 under vs2013. It seems in vs2013 the cls object is deconstructed. Why I got the different returns? and how to make it works well under visual studio? Thanks a lot.

cls.h

#pragma once
#include <iostream>
#include <string>
#define OUT(x)  do{ std::cout << x << std::endl;}while(0)
template <class T> class IBuilder{
public:
    virtual ~IBuilder(){};
    virtual T build() = 0;
};
class cls
{
public:
    ~cls();
    cls(const cls& origin);
    class Builder : public IBuilder<cls>{
    private:
        std::string _name;
        int _stride = 4;        
        double _cascThr = -1;
    public:
        Builder(const std::string name);
        ~Builder();
        Builder* stride(int s);
        Builder* cascThr(double t);
        cls build();
        friend cls;
    };
private:
    std::string _name;
    int _stride;
    double _cascThr;
    Builder* _builder;
    cls(Builder* builder);
    cls& operator=(const cls&);//prevent the compiler to generate copying assignment
};

cls.cpp

#include "cls.h"
using namespace std;
cls::cls(const cls& origin){}
cls::cls(cls::Builder* builder) {
    this->_builder = builder;
    OUT("cls(Builder*)");
    this->_name = builder->_name;   
    this->_stride = builder->_stride;   
    this->_cascThr = builder->_cascThr; 
}
cls::   ~cls(){ 
    OUT("~cls()");
}
cls::Builder::Builder(const string name){
    OUT("Builder(string)");
    this->_name = name;
}
cls::Builder::~Builder(){
    OUT("~Builder() ");
}
cls::Builder* cls::Builder::stride(int s){
    this->_stride = s;
    return this;
}
cls::Builder* cls::Builder::cascThr(double t){
    this->_cascThr = t;
    return this;
}
cls cls::Builder::build(){
    OUT("Build ACF Detector From Builder");
    return cls(this);
}

main.cpp

#include "cls.h"
using namespace std;
cls func(){
    cls::Builder* builder = NULL;
    builder = new cls::Builder("t_name");
    builder->stride(5);
    builder->cascThr(1.0);
    cls detector = builder->build();
    return detector;
}
int _tmain(int argc, _TCHAR* argv[])
{
    cls tt = func(); // here I got different answers.
    return 0;
}

Advertisement

Answer

You have got a copy constructor that does nothing.

cls::cls(const cls& origin){}

GCC probably does copy elision in the lines cls tt = func(); and cls detector = builder->build(); and it magically works. Maybe VS will do it too once you enable optimizations. Personally, I’d say it’s a bug in your code. If you have a copy constructor, then copy the origin object.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement