Re: [Boost-bugs] [Boost C++ Libraries] #2262: BOOST_MPL_ASSERT_MSG producing linking problems in MSVC++ 8.0

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #2262: BOOST_MPL_ASSERT_MSG producing linking problems in MSVC++ 8.0
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-01-13 08:51:06


#2262: BOOST_MPL_ASSERT_MSG producing linking problems in MSVC++ 8.0
-------------------------------------+--------------------------------------
 Reporter: joaquin | Owner: agurtovoy
     Type: Bugs | Status: new
Milestone: Boost 1.37.0 | Component: mpl
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
-------------------------------------+--------------------------------------
Changes (by Juan Jesús García de Soria Lucena <juanj.g_soria@…>):

 * cc: juanj.g_soria@… (added)

Comment:

 Hi, Joaquin!

 We have found this problem when recently converting a template parser from
 spirit classic to spirit 2.1.

 I don't know why it's different when used outside a function, but the
 issue seems to reside in this fragment of boost/mpl/assert.hpp:

    {{{
 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
 # define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \
 struct msg; \
 typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
 { \
     using boost::mpl::assert_::types; \
     static boost::mpl::failed ************ (msg::************
 assert_arg()) types_ \
     { return 0; } \
 } BOOST_PP_CAT(mpl_assert_arg,counter); \
 BOOST_MPL_AUX_ASSERT_CONSTANT( \
       std::size_t \
     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
         boost::mpl::assertion<(c)>::failed(
 BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
         ) \
     ) \
 /**/
 #else
 # define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \
 struct msg; \
 typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
 { \
     static boost::mpl::failed ************ (msg::************
 assert_arg()) types_ \
     { return 0; } \
 } BOOST_PP_CAT(mpl_assert_arg,counter); \
 BOOST_MPL_AUX_ASSERT_CONSTANT( \
       std::size_t \
     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
         boost::mpl::assertion_failed<(c)>(
 BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
         ) \
     ) \
 /**/
 #endif
 }}}

 And actually in the {{{ { return 0; } }}} implementation of the functions,
 that actually produce non-local functions on MSVC 2005. These non-local
 functions then conflict at link time when the counter is the same.

 I tried just leaving the those functions with no body (just the
 declarations), and then the problem went away, although Visual Studio
 would spit a lot of ugly warnings about a local class method with no
 implementation.

 In the end I just removed the auxiliary auto-generated class and typedef,
 and just replaced the call to its member function with an expression that
 would yield the same type:

    {{{
 (boost::mpl::failed ************ (msg::************) types_) 0
 }}}

 This allowed me to remove the {{{#ifdef}}} related to the MetroWerks
 compiler, since it was just changing the now removed structure.

 I've tested this with Visual Studio 2005, and it works. I don't know if it
 will cause problems somewhere else. Perhaps there's some compiler out
 there that can't cast 0 to a pointer-to-member-function type...

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/2262#comment:2>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:02 UTC