[gecode-users] Smart pointer in propagator?

Drescher, Conrad conrad.drescher at sap.com
Thu Apr 14 15:57:43 CEST 2016


Hi Christian,

and thanks again. I think I found something: It seems whether class Propagator has a virtual destructor depends on the compiler. In class Actor in core.hpp it says:

#ifndef __GNUC__
    /// Not used (uses dispose instead)
    static void  operator delete(void* p);
#endif
    /// Not used
    static void* operator new(size_t s);
    //@}
#ifdef __GNUC__
  public:
    /// To avoid warnings from GCC
    GECODE_KERNEL_EXPORT virtual ~Actor(void);
    /// Not used (uses dispose instead)
    static void  operator delete(void* p);
#endif

Do you think we could get the same on Windows without causing any harm?

Best wishes,
Conrad


-----Original Message-----
From: Christian Schulte [mailto:cschulte at kth.se] 
Sent: Mittwoch, 13. April 2016 20:58
To: Drescher, Conrad <conrad.drescher at sap.com>; users at gecode.org
Subject: RE: [gecode-users] Smart pointer in propagator?

* PGP - S/MIME Signed by an unverified key: 13.04.2016 at 20:57:41

Hi Conrad,

That's easy: you do not define a destructor, that's why you get a warning:
 - The class Propagator has a virtual destructor just to avoid warnings.
 - Just define a destructor and the warning goes away.

I guess it comes from the fact that your Less class has a member which
itself has a destructor.

I'd rather ignore it but if you do like warnings at least add an
assert(false) to the destructor!

Cheers
Christian

--
Christian Schulte, www.gecode.org/~schulte
Professor of Computer Science, KTH, cschulte at kth.se
Expert Researcher, SICS, cschulte at sics.se

-----Original Message-----
From: Drescher, Conrad [mailto:conrad.drescher at sap.com] 
Sent: Wednesday, April 13, 2016 16:57
To: Schulte, Christian <cschulte at kth.se>; users at gecode.org
Subject: RE: [gecode-users] Smart pointer in propagator?

Hi Christian,

and many thanks for confirming we're not completely off the track.

We have a propagator that has a shared_ptr member. We follow your basic
guidelines and in the propagator dispose function we reset the shared
pointer (decreasing the reference count). On Linux with gcc 4.8 that
compiles fine and behaves as expected. On Windows with Visual Studio 2015 we
get a warning: 

warning C4265: 'Less': class has virtual functions, but destructor is not
virtual
           instances of this class may not be destructed correctly

(and we're living in a "warning-as-errors"-environment).

Would you happen to have some advice on that issue, too?

Many thanks!
Conrad

The example below can be used to reproduce the behavior on Windows (it
extends the naïve Less-constraint from MPG with an otherwise useless shared
pointer).

#include <memory>
#include <iostream>
#include <gecode/driver.hh>
#include <gecode/int.hh>
#include <gecode/minimodel.hh>
#include <gecode/search.hh>
#include <gecode/kernel.hh>
#include <gecode/support.hh>

using namespace Gecode;

class TestObj{
private:
	int i;
public:
	TestObj(int i1) : i(i1) {
		std::cout << "Constructed" << std::endl;
	}
	~TestObj(){
		std::cout << "Destroyed" << std::endl;
	}
};

class Less : public Propagator {
protected:
	Int::IntView x0, x1;
	std::shared_ptr<TestObj> p;
public:
	// posting
	Less(Space& home, Int::IntView y0, Int::IntView y1,
std::shared_ptr<TestObj> p1) : Propagator(home), x0(y0), x1(y1) {
		x0.subscribe(home,*this,Int::PC_INT_DOM);
		x1.subscribe(home,*this,Int::PC_INT_DOM);
		p = p1;
        home.notice(*this, AP_DISPOSE);
	}
	static ExecStatus post(Space& home, Int::IntView x0, Int::IntView
x1, std::shared_ptr<TestObj> p) {
		(void) new (home) Less(home,x0,x1,p); return ES_OK;
	}
	// disposal
	virtual size_t dispose(Space& home) {
		x0.cancel(home,*this,Int::PC_INT_DOM);
		x1.cancel(home,*this,Int::PC_INT_DOM);
		p.reset();
		//p.~shared_ptr<TestObj>();
		(void) Propagator::dispose(home);
		home.ignore(*this,AP_DISPOSE);
		return sizeof(*this);
	}
	// copying
	Less(Space& home, bool share, Less& prop) :
Propagator(home,share,prop), p(prop.p) {
		x0.update(home,share,prop.x0);
		x1.update(home,share,prop.x1);
	}
	virtual Propagator* copy(Space& home, bool share) {
		return new (home) Less(home,share,*this);
	}
	// cost computation
	virtual PropCost cost(const Space&, const ModEventDelta&) const {
		return PropCost::binary(PropCost::LO);
	}
	// propagation
	virtual ExecStatus propagate(Space& home, const ModEventDelta&) {
		if (x0.le(home,x1.max()) == Int::ME_INT_FAILED)
			return ES_FAILED;
		if (x1.gr(home,x0.min()) == Int::ME_INT_FAILED)
			return ES_FAILED;
		if (x0.assigned() && x1.assigned())
			return home.ES_SUBSUMED(*this);
		else return ES_NOFIX;
	}
};

void less(Space& home, IntVar x0, IntVar x1, std::shared_ptr<TestObj> p) {
// constraint post function
	Int::IntView y0(x0), y1(x1);
	if (Less::post(home,y0,y1,p) != ES_OK) home.fail();

}

class ExampleSpace : public Script {
protected:
  /// Arrays of ints
  IntVarArray intvars;
public:
  /// Actual model

  ExampleSpace(const Options& opt) : Script(opt), intvars(*this,2,0,10) {
     std::shared_ptr<TestObj> p = std::make_shared<TestObj>(1);
	 less(*this,intvars[0],intvars[1],p);
	 branch(*this, intvars, INT_VAR_SIZE_MIN(), INT_VAL_MIN() );
  }
  /// Print solution
  virtual void
  print(std::ostream& os) const {
    os << "\t" << intvars << std::endl;
  }

  /// Constructor for cloning \a s
  ExampleSpace(bool share, ExampleSpace& s) : Script(share,s) {
    intvars.update(*this, share, s.intvars);
  }
  /// Copy during cloning
  virtual Space*
  copy(bool share) {
    return new ExampleSpace(true,*this);
  }
};

int
main(int argc, char* argv[]) {
  Options opt("ExampleSpace");
  opt.parse(argc,argv);
  Script::run<ExampleSpace,DFS,Options>(opt);
  return 0;
}

-----Original Message-----
From: Christian Schulte [mailto:cschulte at kth.se]
Sent: Dienstag, 12. April 2016 21:22
To: Drescher, Conrad <conrad.drescher at sap.com>; users at gecode.org
Subject: RE: [gecode-users] Smart pointer in propagator?

Hi Conrad,

There is a catch here: storing a smart pointer (or any other data structure
that has a destructor) in an object is okay, provided that:
1. You register the propagator so that its dispose() member function is
called when the propagator is deleted. But that you say you do.
2. You add an explicit call to the smart pointer's destructor in the
propagator's dispose() function, for example: if p is the smart pointer of
say type unique_ptr<T>, then add p.¨unique_ptr<T>() to the dispose() member
function.

That should do the trick. Is this worth being added as a tip to MPG?

Cheers
Christian

--
Christian Schulte, http://www.gecode.org/~schulte Professor of Computer
Science, KTH, mailto:cschulte at kth.se Expert Researcher, SICS,
cschulte at sics.se

From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of Drescher, Conrad
Sent: Friday, April 8, 2016 14:24
To: users at gecode.org
Subject: [gecode-users] Smart pointer in propagator?

Hi there,

we were thinking of storing a smart pointer in a propagator that is asking
its home space to call its dispose()-method upon home space deletion. In the
absence of a virtual destructor for class Propagator we're not sure it's a
smart idea. Reading MPG 30.2 did not entirely clarify the situation - could
you please elaborate?

Many thanks!
Conrad

Dr. Conrad Drescher
Senior Developer | AI DEV SCM PLM DE
SAP SE | Dietmar-Hopp-Allee 16 | 69190 Walldorf | Germany T +49 6227 7-77888
| M +49 160 90684883 | E mailto:conrad.drescher at sap.com http://www.sap.com/

Please consider the impact on the environment before printing this e-mail.


Pflichtangaben/Mandatory Disclosure Statements: 
http://www.sap.com/company/legal/impressum.epx

Diese E-Mail kann Betriebs- oder Geschäftsgeheimnisse oder sonstige
vertrauliche Informationen enthalten. Sollten Sie diese E-Mail irrtümlich
erhalten haben, ist Ihnen eine Kenntnisnahme des Inhalts, eine
Vervielfältigung oder Weitergabe der E-Mail ausdrücklich untersagt. Bitte
benachrichtigen Sie uns und vernichten Sie die empfangene E-Mail. Vielen
Dank. 

This e-mail may contain trade secrets or privileged, undisclosed, or
otherwise confidential information. If you have received this e-mail in
error, you are hereby notified that any review, copying, or distribution of
it is strictly prohibited. Please inform us immediately and destroy the
original transmittal. Thank you for your cooperation.



* Christian Schulte <cschulte at kth.se>
* Issuer: TERENA - Unverified



More information about the users mailing list