[cpp-threads] Update on N2889/N2880/N2901

Boehm, Hans hans.boehm at hp.com
Mon Jun 22 23:47:01 BST 2009


> > - Thread locals need destructors in C and C++ (and not in Java) 
> > because there's no GC.
> 
> Interjection: This may have merit, but I do want to push back 
> on this in principle. C++ destructors are much more powerful 
> than Java finalizers. Destructors correspond directly to the 
> Java dispose idiom, not to finalizers. Finalizers are 
> different, and the code you can safely write inside 
> finalizers is much more restrictive (e.g., in which other 
> objects are still valid to access) than what you can write in 
> a destructor.

[We've had the first part of this discussion before, but ...]
I think this is a red herring.  We're picking on Java design flaws that are clearly avoidable.  Java finalizers indeed have issues with finalization order, but there is no reason to copy that design, and there are several ways to avoid those problems anyway, e.g. use java.lang.ref instead.  And in my opinion, Modula 3 got this part right many years earlier.

These issues aside, I think destructors and finalizers are fundamentally incomparable.  Destructors have the big advantage that they run synchronously at predictable points.  They have the big disadvantage that they run synchronously at predictable points, and are thus prone to deadlocks, at least in the absence of something like transactional memory.

But in most cases, I think that neither of these is particularly relevant, since the resources associated with thread-locals are likely to be memory resources anyway, so GC would solve the problem.

Destructors for thread-local shared_ptrs would get us closer to that state.  But I think they already introduce most of the difficultites, since they can use allocators of bounded lifetime.

At least I think they can.  Shared_ptr has a constructor

template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);

However, since the allocator type A is not part of the shared_ptr type, how does this work?  Assuming I construct one with a non-default allocator type but, say, no interesting allocator state a, how does shared_ptr know how to deallocate the reference count on destruction of the final pointer to an object?

This seems strange.  I'm either missing something, or we have another bug in the draft here.

Hans


More information about the cpp-threads mailing list