From: Maciej Sobczak on
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
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
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
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
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! ]