The Joel on Software Discussion Group (CLOSED)

A place to discuss Joel on Software. Now closed.

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

boost::shared_ptr - deletion of incomplete type workaround

Can anyone describe or point me to an article or reference describing how the boost lib avoids problems with deletion of incomplete types in shared_ptr?  I'm trying to write a similar template and for various reasons can't use boost.
CPP'R
Friday, June 23, 2006
 
 
If you look at boost's checked_delete.hpp it's not very complex.

template<class T> inline void checked_delete(T * x)
{
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
}

You can't evaluate the sizeof an incomplete type (or judging from the code some compilers give 0, in which case the array is of negative size which isn't allowed). I assume the sizeof(type_must_be_complete) is to stop the type being optimized out too early.
Ian G Send private email
Friday, June 23, 2006
 
 
Thanks.

Actually, it turned out that my template was correct, but I saw some weirdness with the VS.NET environment.  Basically, I have a console app and a static lib in one solution.  The static lib has a class in it that uses the PIMPL idiom and shared_ptr:

class Foo
{
public:
private:
  class Foo;
  shared_ptr<Foo> pImpl;
};


The console app links to the lib, and instantiates a Foo on the stack.  That's when I got the pointer-to-incomplete type error.

However, BEFORE, I simply made libfoo a dependency of foo.exe.  Once I explicitly added libfoo the the dependencies in the linker settings tab of foo.exe, it compiled cleanly with no warnings.

What's the difference?
CPP'R
Friday, June 23, 2006
 
 
Uhhh.. Ignore my last post.  The *real* problem seems to be when I try to put things in an stl vector..  That's what's causing this issue.  There must be a way around it, no? 

Getting ready to just use boost::shared_ptr...
CPP'R
Friday, June 23, 2006
 
 
Boost has a trick where the boost::shared_ptr allocated on the stack (or wherever) actually holds a pointer to an abstract class, where the instance of that is a template based on the actual types provided when you instantiate the shared_ptr.

This means that the physical size and implementation of a boost::shared_ptr<T,D>  (where D is the deleter, usually using a suitable default) depends on T (in name only) and a pointer to an abstract base class, rather than T and D. The deleter object is stored away in a template class that implements the abstract base and is only ever instantiated when an actual obejct is placed into the pointer, which requires the complete type in order for the 'new' operator to work. I suspect that your template depends on both the type pointed to and the method of deletion (i.e. the 'delete' operator, or a function object that deletes objects), which requires a complete type.

Inserting into a std::vector will require the ability to both copy and delete the object (so that the vector can be expanded if necessary), so the destructor of your class can be called, thus calling the 'delete' operator, and requiring the ability to actually delete the object which would be why you'ld need the complete type.

That might be it, anyway.  ;)


Btw, what's the reason you can't use boost?  Even if shared_ptr is the only class you use, it's probably better to use that than to try and roll your own. Unelss there's a good reason you can't - but that'll probably just require you to reimplement all the complexities yourself, anyway.

Friday, June 23, 2006
 
 
That's gotta be it.  Thanks!

I can't use boost because the big boss is basically against it.  (!)
CPP'R
Saturday, June 24, 2006
 
 
Any good reason for that, or does he have a terminal case of "Not Invented Here" syndrome?

Saturday, June 24, 2006
 
 
Not Invented Here
Not Understood Here
Etc,.
CPP'R
Sunday, June 25, 2006
 
 
One frustration I have with Boost is that it isn't that easy to take just a piece of it.  Trying to get just the shared pointer library into our code base wouldn't be that bad, but a lot of the other libraries are "too wierd".  And you can't quite seem to just download one header, one cpp to get the thing.
Keith Wright Send private email
Monday, June 26, 2006
 
 
I totally agree with the last poster.  Too hard to use some of the good stuff without pulling in the rest of the world.

Hopefully shared_ptr will make it into the standard.  As I understand it, it is currently part of the technical recommendation (TR1)
CPP'R
Monday, June 26, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz