www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Destroying structs without a typeinfo object

reply Benjamin Thaut <code benjamin-thaut.de> writes:
Hi,

I'm currently doing some manual memory management and as the delete 
keyword is deperecated I want to replace it with a custom Delete 
template. I now need to destroy a array of structs, this however seems 
only be possible by using the typeinfo object of the struct and calling 
xdtor on that which is a indirect function call for every struct in the 
array. I would like to destroy the struct directly with a direct call to 
the destructor. This seems not to be possible because calling __dtor 
results in calling the wrong dtor (apperently there are 3, __dtor, 
__fieldDtor, __aggrDtor). So __dtor is the wrong destructor because it 
does not destroy any members of the struct but __fieldDtor and 
__aggrDtor are not callable. They show up in the __traits(allMembers) 
list but if you try to call them you get a error message that such a 
property does not exist. So is there any way to directly destroy a 
struct, and if not why can't we directly expose the correct destructor, 
because apprently it is known at compile time.

Kind Regards
Benjamin Thaut
May 03 2012
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 May 2012 02:45:03 -0400, Benjamin Thaut  
<code benjamin-thaut.de> wrote:

 Hi,

 I'm currently doing some manual memory management and as the delete  
 keyword is deperecated I want to replace it with a custom Delete  
 template. I now need to destroy a array of structs, this however seems  
 only be possible by using the typeinfo object of the struct and calling  
 xdtor on that which is a indirect function call for every struct in the  
 array. I would like to destroy the struct directly with a direct call to  
 the destructor. This seems not to be possible because calling __dtor  
 results in calling the wrong dtor (apperently there are 3, __dtor,  
 __fieldDtor, __aggrDtor). So __dtor is the wrong destructor because it  
 does not destroy any members of the struct but __fieldDtor and  
 __aggrDtor are not callable. They show up in the __traits(allMembers)  
 list but if you try to call them you get a error message that such a  
 property does not exist. So is there any way to directly destroy a  
 struct, and if not why can't we directly expose the correct destructor,  
 because apprently it is known at compile time.

Look at what object.clear() does, since it is meant to replace delete. In fact, I'd advise just using that if you have the type handy. -Steve
May 04 2012
next sibling parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
Am 04.05.2012 14:18, schrieb Steven Schveighoffer:
 On Fri, 04 May 2012 02:45:03 -0400, Benjamin Thaut
 <code benjamin-thaut.de> wrote:

 Hi,

 I'm currently doing some manual memory management and as the delete
 keyword is deperecated I want to replace it with a custom Delete
 template. I now need to destroy a array of structs, this however seems
 only be possible by using the typeinfo object of the struct and
 calling xdtor on that which is a indirect function call for every
 struct in the array. I would like to destroy the struct directly with
 a direct call to the destructor. This seems not to be possible because
 calling __dtor results in calling the wrong dtor (apperently there are
 3, __dtor, __fieldDtor, __aggrDtor). So __dtor is the wrong destructor
 because it does not destroy any members of the struct but __fieldDtor
 and __aggrDtor are not callable. They show up in the
 __traits(allMembers) list but if you try to call them you get a error
 message that such a property does not exist. So is there any way to
 directly destroy a struct, and if not why can't we directly expose the
 correct destructor, because apprently it is known at compile time.

Look at what object.clear() does, since it is meant to replace delete. In fact, I'd advise just using that if you have the type handy. -Steve

object.clear() useses the typeinfo.destroy() method which is a virtual function call plus a indirect function call. So thats even one level of indirection more. Also clear does reinitializle the struct after destroying it, which is completely unneccesary in my case, because I'm about to free the memory anyway. Kind Regards Benjamin Thaut
May 04 2012
parent Benjamin Thaut <code benjamin-thaut.de> writes:
Am 04.05.2012 15:14, schrieb Steven Schveighoffer:
 On Fri, 04 May 2012 08:38:21 -0400, Benjamin Thaut
 <code benjamin-thaut.de> wrote:

 Am 04.05.2012 14:18, schrieb Steven Schveighoffer:
 On Fri, 04 May 2012 02:45:03 -0400, Benjamin Thaut
 <code benjamin-thaut.de> wrote:

 Hi,

 I'm currently doing some manual memory management and as the delete
 keyword is deperecated I want to replace it with a custom Delete
 template. I now need to destroy a array of structs, this however seems
 only be possible by using the typeinfo object of the struct and
 calling xdtor on that which is a indirect function call for every
 struct in the array. I would like to destroy the struct directly with
 a direct call to the destructor. This seems not to be possible because
 calling __dtor results in calling the wrong dtor (apperently there are
 3, __dtor, __fieldDtor, __aggrDtor). So __dtor is the wrong destructor
 because it does not destroy any members of the struct but __fieldDtor
 and __aggrDtor are not callable. They show up in the
 __traits(allMembers) list but if you try to call them you get a error
 message that such a property does not exist. So is there any way to
 directly destroy a struct, and if not why can't we directly expose the
 correct destructor, because apprently it is known at compile time.

Look at what object.clear() does, since it is meant to replace delete. In fact, I'd advise just using that if you have the type handy. -Steve

object.clear() useses the typeinfo.destroy() method which is a virtual function call plus a indirect function call. So thats even one level of indirection more. Also clear does reinitializle the struct after destroying it, which is completely unneccesary in my case, because I'm about to free the memory anyway.

Look at what TypeInfo_Struct.destroy() does: override void destroy(void* p) { if (xdtor) (*xdtor)(p); } So here is what I'd suggest (for an array of struct S): auto ti = typeid(S).xdtor; if(xdtor) foreach(ref s; arr) (*xdtor)(&s); Which should be as efficient as possible, given the current implementation, you don't have to repeat the lookup for each element. I remember that __dtor does the wrong thing, and I advocated it should do the same thing as calling xdtor, but it didn't go anywhere. -Steve

Thanks, but thats exactly what I'm currently doing. This still is a indirect function call, and I hoped that there is a way to directly call the destructor. Kind Regards Benjamin Thaut
May 04 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 May 2012 08:38:21 -0400, Benjamin Thaut  
<code benjamin-thaut.de> wrote:

 Am 04.05.2012 14:18, schrieb Steven Schveighoffer:
 On Fri, 04 May 2012 02:45:03 -0400, Benjamin Thaut
 <code benjamin-thaut.de> wrote:

 Hi,

 I'm currently doing some manual memory management and as the delete
 keyword is deperecated I want to replace it with a custom Delete
 template. I now need to destroy a array of structs, this however seems
 only be possible by using the typeinfo object of the struct and
 calling xdtor on that which is a indirect function call for every
 struct in the array. I would like to destroy the struct directly with
 a direct call to the destructor. This seems not to be possible because
 calling __dtor results in calling the wrong dtor (apperently there are
 3, __dtor, __fieldDtor, __aggrDtor). So __dtor is the wrong destructor
 because it does not destroy any members of the struct but __fieldDtor
 and __aggrDtor are not callable. They show up in the
 __traits(allMembers) list but if you try to call them you get a error
 message that such a property does not exist. So is there any way to
 directly destroy a struct, and if not why can't we directly expose the
 correct destructor, because apprently it is known at compile time.

Look at what object.clear() does, since it is meant to replace delete. In fact, I'd advise just using that if you have the type handy. -Steve

object.clear() useses the typeinfo.destroy() method which is a virtual function call plus a indirect function call. So thats even one level of indirection more. Also clear does reinitializle the struct after destroying it, which is completely unneccesary in my case, because I'm about to free the memory anyway.

Look at what TypeInfo_Struct.destroy() does: override void destroy(void* p) { if (xdtor) (*xdtor)(p); } So here is what I'd suggest (for an array of struct S): auto ti = typeid(S).xdtor; if(xdtor) foreach(ref s; arr) (*xdtor)(&s); Which should be as efficient as possible, given the current implementation, you don't have to repeat the lookup for each element. I remember that __dtor does the wrong thing, and I advocated it should do the same thing as calling xdtor, but it didn't go anywhere. -Steve
May 04 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 May 2012 09:14:11 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 I remember that __dtor does the wrong thing, and I advocated it should  
 do the same thing as calling xdtor, but it didn't go anywhere.

See this bug report: http://d.puremagic.com/issues/show_bug.cgi?id=5667 -Steve
May 04 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 May 2012 11:20:41 -0400, Benjamin Thaut  
<code benjamin-thaut.de> wrote:
 Thanks, but thats exactly what I'm currently doing. This still is a  
 indirect function call, and I hoped that there is a way to directly call  
 the destructor.

Then no, there isn't a better way. If you look at that bug report, you can see there is no callable symbol the compiler will recognize to call that function directly. -Steve
May 04 2012