Topic: Deletion of pointer to incomplete class


Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1996/11/15
Raw View
vandevod@cs.rpi.edu (David Vandevoorde) wrote (in
comp.lang.c++.moderated):

>>>>>> "MF" == Michael Furman <engr@gssi.mv.com> writes:
>MF> C:\Projects\Tomo\Tprepare\TprpDoc.cpp(48) : warning C4150:
>MF> deletion of pointer to incomplete type 'Tscan'; no destructor called
>
>MF> Why it is only warning? IMO it should be an error.
>MF> Is it MS problem or I am wrong and it is legal?
>
>No, it's legal, but whatever the complete type is, the behaviour is
>undefined if its destructor is nontrivial or if it has an overloaded
>operator delete member.

In fact, it seems to me that the behavior could be undefined even if it
has a trivial destructor and does not overload delete. Operators new and
delete are not required to keep track of the size of the object
allocated. For systems that do not keep track of the size of allocated
blocks, it is up to the compiler and run-time system to supply the size
at delete time. In the case of an incomplete type, it cannot do so and
the system cannot free more than one byte, regardless of how large the
allocated object is. Thus, it would seem to be undefined behavior
*always*.  IMHO, the standard should not allow undefined run-time
behavior if it can be caught at compile time, instead.

I really don't understand the theory behind allowing deletion of
incomplete types. The idea that it has something to do with C-style
structs makes no sense to me since C code doesn't use new and delete.

I have set follow-ups to comp.std.c++.

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
those of my employer.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Chelly Green <chelly@eden.com>
Date: 1996/11/16
Raw View
Pablo Halpern wrote:
>
> vandevod@cs.rpi.edu (David Vandevoorde) wrote (in
> comp.lang.c++.moderated):
>
> >>>>>> "MF" == Michael Furman <engr@gssi.mv.com> writes:
> >MF> C:\Projects\Tomo\Tprepare\TprpDoc.cpp(48) : warning C4150:
> >MF> deletion of pointer to incomplete type 'Tscan'; no destructor called
> >
> >MF> Why it is only warning? IMO it should be an error.
> >MF> Is it MS problem or I am wrong and it is legal?
> >
> >No, it's legal, but whatever the complete type is, the behaviour is
> >undefined if its destructor is nontrivial or if it has an overloaded
> >operator delete member.
>
> In fact, it seems to me that the behavior could be undefined even if it
> has a trivial destructor and does not overload delete. Operators new and
> delete are not required to keep track of the size of the object
> allocated.

Custom operator new doesn't if there is a custom operator delete that
takes a size_t as its second argument. Otherwise it must have some way
of freeing the storage without the compiler giving it the size of the
object.

> For systems that do not keep track of the size of allocated
> blocks, it is up to the compiler and run-time system to supply the size
> at delete time.

How can these work with C++? ::operator new and ::operator delete need
to keep track of the size information, since ::operator delete can't
take a size_t argument.

> In the case of an incomplete type, it cannot do so and
> the system cannot free more than one byte, regardless of how large the
> allocated object is.

It just calls ::operator delete with the object pointer. This is why it
is legal, because a type with a trivial destructors, and no custom
allocator, is deleted in this way.

Here is the relevant clip from the April 1995 Draft Standard:

>   5.3.5  Delete                                            [expr.delete]
>
...
> 5 If the object being deleted has incomplete class type at the point  of
>   deletion  and  the class has a non-trivial destructor or an allocation
>   function or a deallocation function, the behavior is undefined.
...

> Thus, it would seem to be undefined behavior
> *always*.  IMHO, the standard should not allow undefined run-time
> behavior if it can be caught at compile time, instead.

Assuming catching it isn't too difficult. For this issue, it certainly
isn't. But it is legal, I guess because lots of code depends on it or it
is useful in some way. I prefer the warning, because it is very likely
an error. I would rather not be able to delete pointers to incomplete
types than have to deal with the hard-to-catch errors caused by allowing
the deletion.

> I really don't understand the theory behind allowing deletion of
> incomplete types. The idea that it has something to do with C-style
> structs makes no sense to me since C code doesn't use new and delete.

Really, that's what I was thinking when someone else mentioned C
compatibility.

--
Chelly Green | chelly@eden.com | C++ - http://www.eden.com/~chelly
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Stein Somers <somers@intec.rug.ac.be>
Date: 1996/11/18
Raw View
Pablo Halpern wrote:
> I really don't understand the theory behind allowing deletion of
> incomplete types. The idea that it has something to do with C-style
> structs makes no sense to me since C code doesn't use new and delete.

I read somewhere some while ago that in the early days of C++, people
tossed out 'struct X*x=(struct X*)malloc(sizeof struct X)' for a safer
and simpler 'X*x=new X'. C++ as a better C I guess. Maybe at some
stage there were no constructors and destructors yet.

Now all C and C++ syntax and other weirdness has been accumulated
in the standard so that the old broken code can freely be mixed with
the new broken code.

--
Stein Somers
Software engineer
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]