cannot pass objects of non-POD type ‘class boost::detail::shared_count’ through ‘...’; call will abort at runtime

Hi Folks [ Sorry if this gets posted twice; my company email server changed my email address, and I think my first post got bounced. Argh.] Just tried to compile my project with GCC 4.3 and Boost 1.40. (It compiles and works just fine with Boost 1.38.) As part of a home-built thread-locking shared pointer thing, we have this code: /// Constructor from pointer to complete type template<class Y> explicit shared_locking_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( pn, p, p ); } which now produces this result: ../util/thread/shared_locking_ptr.hpp:57:9: warning: cannot pass objects of non-POD type ‘class boost::detail::shared_count’ through ‘...’; call will abort at runtime In Boost 1.38, the relevent code in shared_ptr.hpp was this AFAICT: #ifdef _MANAGED [ ... ] #else // _MANAGED [...] inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) { } #endif // _MANAGED In 1.40, it's been changed to #ifdef _MANAGED [...] #else // _MANAGED inline void sp_enable_shared_from_this( ... ) { } #endif // _MANAGED Does anyone know why the change? Has anybody else seen this problem? It seems to me that GCC is correct, and that although it's an empty function so it doesn't matter anyway, the earlier version is preferable. Alternately, does anyone know of a way to silence GCC's warning? -- Dave Steffen, Ph.D - Software Engineer Numerica Corporation (www.numerica.us <http://www.numerica.us/> ) 4850 Hahns Peak Drive, Suite 200 Loveland, Colorado 80538 main (970) 461-2000 x 227 direct (970) 612-2327 fax (970) 461-2004 Email: dave.steffen@numerica.us

Dave Steffen wrote:
Hi Folks
[ Sorry if this gets posted twice; my company email server changed my email address, and I think my first post got bounced. Argh.]
Just tried to compile my project with GCC 4.3 and Boost 1.40. (It compiles and works just fine with Boost 1.38.)
As part of a home-built thread-locking shared pointer thing, we have this code:
/// Constructor from pointer to complete type template<class Y> explicit shared_locking_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( pn, p, p ); }
which now produces this result:
../util/thread/shared_locking_ptr.hpp:57:9: warning: cannot pass objects of non-POD type ‘class boost::detail::shared_count’ through ‘...’; call will abort at runtime
In Boost 1.38, the relevent code in shared_ptr.hpp was this AFAICT: #ifdef _MANAGED [ ... ] #else // _MANAGED [...]
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) { }
#endif // _MANAGED
In 1.40, it's been changed to
#ifdef _MANAGED [...] #else // _MANAGED
inline void sp_enable_shared_from_this( ... ) { }
#endif // _MANAGED
Does anyone know why the change?
The signature of sp_enable_shared_from_this has changed, it now takes a pointer to a shared_ptr as its first argument. Look at the current shared_ptr constructor: template<class Y> explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( this, p, p ); } Relying on implementation details has its maintenance costs. :-) You'll probably need to refactor shared_locking_ptr to contain (or privately derive from) a shared_ptr.

Am Thursday 17 September 2009 14:58:23 schrieb Peter Dimov:
The signature of sp_enable_shared_from_this has changed, it now takes a pointer to a shared_ptr as its first argument. Look at the current shared_ptr constructor:
template<class Y> explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( this, p, p ); }
Relying on implementation details has its maintenance costs. :-)
I wondered before why shared_count is an implementation detail. there are obviously use cases besides shared_ptr for this. one of those use cases is even endorsed by boost, by offering intrusive_ptr. and the implementation of shared_count has performance advantages over every portable solution possible, as its implemented compiler- and platform-specific for many combinations. so, why's shared_count an implementation detail?

Stefan Strasser wrote:
I wondered before why shared_count is an implementation detail. there are obviously use cases besides shared_ptr for this. one of those use cases is even endorsed by boost, by offering intrusive_ptr. and the implementation of shared_count has performance advantages over every portable solution possible, as its implemented compiler- and platform-specific for many combinations. so, why's shared_count an implementation detail?
You probably meant atomic_count? If so, it's not a part of shared_ptr, although it's still a very useful tool indeed. I believe, it's still an implementation detail in hope that there will appear a C++1x std::atomic implementation one day.

Stefan Strasser wrote:
Am Thursday 17 September 2009 14:58:23 schrieb Peter Dimov:
The signature of sp_enable_shared_from_this has changed, it now takes a pointer to a shared_ptr as its first argument. Look at the current shared_ptr constructor:
template<class Y> explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( this, p, p ); }
Relying on implementation details has its maintenance costs. :-)
I wondered before why shared_count is an implementation detail.
Well, in this specific case the implementation detail being relied on is sp_enable_shared_from_this, not shared_count. shared_count being pubic and documented wouldn't have helped.
there are obviously use cases besides shared_ptr for this. one of those use cases is even endorsed by boost, by offering intrusive_ptr. and the implementation of shared_count has performance advantages over every portable solution possible, as its implemented compiler- and platform-specific for many combinations. so, why's shared_count an implementation detail?
Originally, the reason was that we didn't want to overspecify shared_ptr. Later on, the reason was that exposing shared_count and its relationship with shared_ptr would have allowed people to get around the eventual limitations of the shared_ptr interface; since std::shared_ptr has no std::shared_count, this would have meant that std::shared_ptr could be left suboptimal. One might argue that these reasons are no longer valid, although I still have my doubts. It'd be better for people's code to port cleanly between boost::shared_ptr and std::shared_ptr. There is indeed the option of documenting shared_count but not its relationship with shared_ptr, but this would just invite the obvious follow-up questions.
participants (4)
-
Andrey Semashev
-
Dave Steffen
-
Peter Dimov
-
Stefan Strasser