|
Prev: Examing an execution, caught by "catch (...)" possible?
Next: C++ Memory Management Innovation: GC Allocator
From: Maciej Sobczak on 22 Apr 2008 02:13 On 22 Kwi, 04:43, internetpet <internet...(a)hotmail.com> wrote: > If you run this you'll see that the Clazz destructor will not be > called when BigClazz does "delete pclazz;" in it's own destructor. 5.3.5/5: "If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined." If you *know* that the destructor was not called, then apparently you have put some code in there so that you were able to recognize it - printing something on the screen, maybe? In any case, your destructor is not trivial and class declaration gives you only the incomplete type for deletion. As cited above, this is undefined behavior. Don't delete objects if their class is only forward-declared. -- Maciej Sobczak * www.msobczak.com * www.inspirel.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: alasham.said on 22 Apr 2008 02:18 On Apr 22, 4:43 am, internetpet <internet...(a)hotmail.com> wrote: > Say you have these files: > > BigClazz.h > > class Clazz; // Note the forward declaration only , no include > "Clazz.h" > class BigClazz > { > public: > BigClazz(); > ~BigClazz(); > Clazz* pclazz; > }; > > BigClazz.cpp > > #include "BigClazz.h" > BigClazz::BigClazz(){} > BigClazz::~BigClazz() > { > delete pclazz; // Here the destructor of of the Clazz object > will not be called > } > > Clazz.h > > class Clazz > { > public: > Clazz(); > ~Clazz(); > }; > > Clazz.cpp > > #include "Clazz.h" > Clazz::Clazz(){}; > Clazz::~Clazz(){}; > > main.cpp > > int main(int argc, char *argv[]) > { > BigClazz* pVM = new BigClazz(); > pVM->pclazz = new Clazz(); > delete pVM; > } > > If you run this you'll see that the Clazz destructor will not be > called when BigClazz does "delete pclazz;" in it's own destructor. But > if you replace the forward declaration in BigClazz (class Clazz;) with > an include > (#include "Clazz.h") then it works. > > Any idea why? > > Thanks > Eric > I believe this falls under "undefined behaviour". So it will depend on the implementation, among other things. From the standard 5.3.5: "If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined." Regards. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Brendan on 22 Apr 2008 02:13 On Apr 21, 7:43 pm, internetpet <internet...(a)hotmail.com> wrote: > Say you have these files: > > BigClazz.h > > class Clazz; // Note the forward declaration only , no include > "Clazz.h" > class BigClazz > { > public: > BigClazz(); > ~BigClazz(); > Clazz* pclazz; > }; > > BigClazz.cpp > > #include "BigClazz.h" > BigClazz::BigClazz(){} > BigClazz::~BigClazz() > { > delete pclazz; // Here the destructor of of the Clazz object > will not be called > } > > Clazz.h > > class Clazz > { > public: > Clazz(); > ~Clazz(); > }; > > Clazz.cpp > > #include "Clazz.h" > Clazz::Clazz(){}; > Clazz::~Clazz(){}; > > main.cpp > > int main(int argc, char *argv[]) > { > BigClazz* pVM = new BigClazz(); > pVM->pclazz = new Clazz(); > delete pVM; > } > > If you run this you'll see that the Clazz destructor will not be > called when BigClazz does "delete pclazz;" in it's own destructor. But > if you replace the forward declaration in BigClazz (class Clazz;) with > an include > (#include "Clazz.h") then it works. What I'm actually iffy on, is why you can compile code that deletes a pointer to an incomplete type at all. This compiles with only a warning about deleting a pointer to an incomplete type on VC9. Can someone who is more of a language lawyer than I comment on if this is permissible in the standard, and if so, why? It seems to me that deleting an incomplete type would always be a mistake... -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: nickf3 on 22 Apr 2008 02:43 Eric, Here's what gcc says with -Wall -pedantic: In destructor `BigClazz::~BigClazz()': warning: possible problem detected in invocation of delete operator: warning: invalid use of undefined type `struct Clazz' warning: forward declaration of `struct Clazz' note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined. In short - you're supposed to include your Clazz.h in the BigClazz.cpp before defining the BigClazz's destructor. -- Nikolai -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alan Johnson on 22 Apr 2008 02:43 internetpet wrote: > Say you have these files: > > BigClazz.h > > class Clazz; // Note the forward declaration only , no include > "Clazz.h" > class BigClazz > { > public: > BigClazz(); > ~BigClazz(); > Clazz* pclazz; > }; > > BigClazz.cpp > > #include "BigClazz.h" > BigClazz::BigClazz(){} > BigClazz::~BigClazz() > { > delete pclazz; // Here the destructor of of the Clazz object > will not be called > } > > Clazz.h > > class Clazz > { > public: > Clazz(); > ~Clazz(); > }; > > > Clazz.cpp > > #include "Clazz.h" > Clazz::Clazz(){}; > Clazz::~Clazz(){}; > > > main.cpp > > int main(int argc, char *argv[]) > { > BigClazz* pVM = new BigClazz(); > pVM->pclazz = new Clazz(); > delete pVM; > } > > If you run this you'll see that the Clazz destructor will not be > called when BigClazz does "delete pclazz;" in it's own destructor. But > if you replace the forward declaration in BigClazz (class Clazz;) with > an include > (#include "Clazz.h") then it works. > > Any idea why? > > Thanks > Eric > > C++ standard -- 5.3.5.5: "If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined." A forward declaration gives you an incomplete type. Thus what you are trying to do is undefined behavior. Think about it from a compiler implementor's viewpoint. If you are emitting code for "delete pclazz;", but you don't know whether or not pclazz even has a destructor, how are you going to emit code that calls it? -- Alan Johnson [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Examing an execution, caught by "catch (...)" possible? Next: C++ Memory Management Innovation: GC Allocator |