
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Phil Bouchard Sent: Tuesday, July 08, 2008 1:46 AM
"Chris Newbold" <Chris.Newbold@mathworks.com> wrote in message news:6F6A2FC198A0F943ACC2259C38A2E30B6688EDD1B4@EXCHANGE- AH.ad.mathworks.com...
[...]
Just for grins, try printing a message out from the destructor of owned_base::pool (or setting a breakpoint there) and see how many times you wind up there. My hunch is that this is an ODR issue...
I get the following:
...
BTW I have gotten the same problem by using Gcc 4.3 and I am not linking multiple source files. Here is my build process: $ g++ shifted_ptr_test2.cpp -I ../../..
I've been able to reproduce this failure in my local sandbox, using GCC 4.1.2. My initial ODR hypothesis was not right, but was close: we're having a static-initialization ordering issue. Pool's fast_pool_allocator class uses singleton_pool to manage a single underlying pool based on the requested size. Singleton_pool in turn uses singleton_default (found in pool/detail/singleton.hpp) which tries _really_ hard to force the compiler to construct the controlled instance at just the right time. What's happening in your test case is that the namespace-scoped owned_base::pool instance (line 187 in sh_owned_base_nt.hpp) is actually being constructed by the compiler _before_ the namespace-scoped initializer object (called create_object, at line 95 in pool/detail/singleton.hpp). That in turn results in the compiler destructing the singleton pool _before_ destructing your owned_base::pool instance. Thus the memory containing the list nodes of the two std::list instanced contained in owned_base::pool is has been freed by the time the list destructors run. I'm a little hard-pressed to make a call as to whether the problem is with GCC's initialization ordering or whether the "cleverness" in pool/detail/singleton.hpp is simply bankrupt and is trying to guarantee something which the language standard cannot. The namespace-scoped initializer generated in pool/detail/singleton.hpp lexically precedes the declaration of the client in sh_owned_base_nt.hpp. Since this test case is a single translation unit, this should in theory ensure that the former is constructed before the latter. However, there's some indirection and function-scoped static objects in play here, too, which may render that guarantee meaningless. I'd be interested to get some additional eyes on the code in pool/detail/singleton.hpp (there's a decent comment there about how it's supposed to work) and see if there can be a reasonable expectation for it to work on a conforming compiler... -Chris