Boost C++ Libraries: Ticket #2262: BOOST_MPL_ASSERT_MSG producing linking problems in MSVC++ 8.0 https://svn.boost.org/trac10/ticket/2262 <p> Steps to reproduce the problem: </p> <ul><li>Create a basic console project in Visual Studio 2005<br /> </li><li>Include files foo1.cpp and foo2.cpp<br /> </li><li>Build; the following error shows up at linking time:<br /> </li></ul><pre class="wiki">&gt;Linking... &gt;foo2.obj : error LNK2005: "public: static struct boost::mpl::failed * * * * * * * * * * * * (__thiscall `bool __cdecl f&lt;int&gt;(void)'::`2' ::ALWAYS_TRUE::** * * * * * * * * * * __cdecl `bool __cdecl f&lt;int&gt; (void)'::`2'::ALWAYS_TRUE0::assert_arg(void))(int)" (?assert_arg@ALWAYS_TRUE0@?1???$f@H@@YA_NXZ@SAPAPAPAPAPAPAPAPAPAPAPAP8 ALWAYS_TRUE@?1???$f@H@@YA_NXZ@AEPAPAPAPAPAPAPAPAPAPAPAPAUfailed@mpl@boost@@H@ZXZ) already defined in foo1.obj </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2262 Trac 1.4.3 Joaquín M López Muñoz Tue, 26 Aug 2008 15:45:11 GMT attachment set https://svn.boost.org/trac10/ticket/2262 https://svn.boost.org/trac10/ticket/2262 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">code.zip</span> </li> </ul> Ticket Joaquín M López Muñoz Tue, 26 Aug 2008 15:51:57 GMT <link>https://svn.boost.org/trac10/ticket/2262#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2262#comment:1</guid> <description> <p> Additional comment: the duplicate symbol problem only happens when BOOST_MPL_ASSERT_MSG is used at function or member function level; at class level everything works OK. </p> </description> <category>Ticket</category> </item> <item> <author>Juan Jesús García de Soria Lucena <juanj.g_soria@…></author> <pubDate>Wed, 13 Jan 2010 08:51:01 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/2262#comment:2 https://svn.boost.org/trac10/ticket/2262#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">juanj.g_soria@…</span> added </li> </ul> <p> Hi, Joaquin! </p> <p> We have found this problem when recently converting a template parser from spirit classic to spirit 2.1. </p> <p> 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: </p> <pre class="wiki">#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&lt;(c)&gt;::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&lt;(c)&gt;( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \ ) \ ) \ /**/ #endif </pre><p> And actually in the <code> { return 0; } </code> 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. </p> <p> 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. </p> <p> 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: </p> <pre class="wiki">(boost::mpl::failed ************ (msg::************) types_) 0 </pre><p> This allowed me to remove the <code>#ifdef</code> related to the <a class="missing wiki">MetroWerks</a> compiler, since it was just changing the now removed structure. </p> <p> 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... </p> Ticket Juan Jesús García de Soria Lucena <juanj.g_soria@…> Wed, 13 Jan 2010 08:52:42 GMT attachment set https://svn.boost.org/trac10/ticket/2262 https://svn.boost.org/trac10/ticket/2262 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_assert_fix.diff</span> </li> </ul> <p> Patch to assert.hpp, fixing BOOST_MPL_ASSERT_MSG link errors. </p> Ticket hustzhanglin@… Fri, 19 Apr 2013 02:16:07 GMT <link>https://svn.boost.org/trac10/ticket/2262#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2262#comment:3</guid> <description> <p> how to solve the error:&#34;c&#34; Undeclared identifier.. </p> </description> <category>Ticket</category> </item> </channel> </rss>