Boost C++ Libraries: Ticket #1892: boost::spirit::static_ causes link error (using wave) https://svn.boost.org/trac10/ticket/1892 <p> When using wave, I encounter a link error when attempting to #include wave headers in more than one translation unit. Although this is via use of wave, I believe it is due to a breaking change in spirit. There is no error in 1.34. This effectively renders wave/spirit next to useless as it forces users to use one source file in their projects. </p> <p> The link error text is (vs2005): 1&gt;token_output.obj : error LNK2005: "public: <span class="underline">thiscall <code>public: __thiscall boost::spirit::static_&lt;class boost::thread_specific_ptr&lt;class boost::weak_ptr&lt;struct boost::spirit::impl::grammar_helper&lt;struct boost::spirit::grammar&lt;class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context&lt;struct boost::spirit::nil_t&gt; &gt;,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner&lt;char const *,struct boost::spirit::scanner_policies&lt;struct boost::spirit::skipper_iteration_policy&lt;struct boost::spirit::iteration_policy&gt;,struct boost::spirit::match_policy,struct boost::spirit::action_policy&gt; &gt; &gt; &gt; &gt;,class boost::spirit::impl::get_definition_static_data_tag&gt;::static_&lt;class boost::thread_specific_ptr&lt;class boost::weak_ptr&lt;struct boost::spirit::impl::grammar_helper&lt;struct boost::spirit::grammar&lt;class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context&lt;struct boost::spirit::nil_t&gt; &gt;,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner&lt;char const *,struct boost::spirit::scanner_policies&lt;struct boost::spirit::skipper_iteration_policy&lt;struct boost::spirit::iteration_policy&gt;,struct boost::spirit::match_policy,struct boost::spirit::action_policy&gt; &gt; &gt; &gt; &gt;,class boost::spirit::impl::get_definition_static_data_tag&gt;(class boost::spirit::impl::get_definition_static_data_tag)'::</code>2'::destructor::~destructor(void)" (??1destructor@?1???0?$static_@V?$thread_specific_ptr@V?$weak_ptr@U?$grammar_helper@U?$grammar@Vtime_conversion_grammar@time_conversion@util@wave@boost@@U?$parser_context@Unil_t@spirit@boost@@@spirit@5@@spirit@boost@@Vtime_conversion_grammar@time_conversion@util@wave@3@V?$scanner@PBDU?$scanner_policies@U?$skipper_iteration_policy@Uiteration_policy@spirit@boost@@@spirit@boost@@Umatch_policy@23@Uaction_policy@23@@spirit@boost@@@23@@impl@spirit@boost@@@boost@@@boost@@Vget_definition_static_data_tag@impl@spirit@2@@spirit@boost@@QAE@Vget_definition_static_data_tag@impl@23@@Z@QAE@XZ) already defined in scramble.obj 1&gt;token_output.obj : error LNK2005: "public: static void </span>cdecl <code>public: __thiscall boost::spirit::static_&lt;class boost::thread_specific_ptr&lt;class boost::weak_ptr&lt;struct boost::spirit::impl::grammar_helper&lt;struct boost::spirit::grammar&lt;class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context&lt;struct boost::spirit::nil_t&gt; &gt;,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner&lt;char const *,struct boost::spirit::scanner_policies&lt;struct boost::spirit::skipper_iteration_policy&lt;struct boost::spirit::iteration_policy&gt;,struct boost::spirit::match_policy,struct boost::spirit::action_policy&gt; &gt; &gt; &gt; &gt;,class boost::spirit::impl::get_definition_static_data_tag&gt;::static_&lt;class boost::thread_specific_ptr&lt;class boost::weak_ptr&lt;struct boost::spirit::impl::grammar_helper&lt;struct boost::spirit::grammar&lt;class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context&lt;struct boost::spirit::nil_t&gt; &gt;,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner&lt;char const *,struct boost::spirit::scanner_policies&lt;struct boost::spirit::skipper_iteration_policy&lt;struct boost::spirit::iteration_policy&gt;,struct boost::spirit::match_policy,struct boost::spirit::action_policy&gt; &gt; &gt; &gt; &gt;,class boost::spirit::impl::get_definition_static_data_tag&gt;(class boost::spirit::impl::get_definition_static_data_tag)'::</code>3'::default_ctor::construct(void)" (?construct@default_ctor@?2???0?$static_@V?$thread_specific_ptr@V?$weak_ptr@U?$grammar_helper@U?$grammar@Vtime_conversion_grammar@time_conversion@util@wave@boost@@U?$parser_context@Unil_t@spirit@boost@@@spirit@5@@spirit@boost@@Vtime_conversion_grammar@time_conversion@util@wave@3@V?$scanner@PBDU?$scanner_policies@U?$skipper_iteration_policy@Uiteration_policy@spirit@boost@@@spirit@boost@@Umatch_policy@23@Uaction_policy@23@@spirit@boost@@@23@@impl@spirit@boost@@@boost@@@boost@@Vget_definition_static_data_tag@impl@spirit@2@@spirit@boost@@QAE@Vget_definition_static_data_tag@impl@34@@Z@SAXXZ) already defined in scramble.obj </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/1892 Trac 1.4.3 eric.malenfant@… Wed, 09 Jul 2008 14:06:40 GMT attachment set https://svn.boost.org/trac10/ticket/1892 https://svn.boost.org/trac10/ticket/1892 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">reproduce1892.zip</span> </li> </ul> <p> Source files to reproduce the link errors </p> Ticket eric.malenfant@… Wed, 09 Jul 2008 14:10:00 GMT <link>https://svn.boost.org/trac10/ticket/1892#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1892#comment:1</guid> <description> <p> Proposed fix: </p> <blockquote> <p> Move the definitions of the "destructor" and "default_constructor" out of static_'s ctor body, and put them inside the class template definition instead. </p> </blockquote> <p> A patch against Boost release 1.35 of /boost/spirit/core/non_terminal/impl/static.hpp gives: </p> <pre class="wiki">@@ -40,20 +40,15 @@ struct static_ : boost::noncopyable { - typedef T value_type; - typedef typename boost::call_traits&lt;T&gt;::reference reference; - typedef typename boost::call_traits&lt;T&gt;::const_reference const_reference; - - static_(Tag = Tag()) - { - struct destructor + private: + struct destructor { ~destructor() { static_::get_address()-&gt;~value_type(); } }; - + struct default_ctor { static void construct() @@ -63,6 +58,13 @@ } }; + public: + typedef T value_type; + typedef typename boost::call_traits&lt;T&gt;::reference reference; + typedef typename boost::call_traits&lt;T&gt;::const_reference const_reference; + + static_(Tag = Tag()) + { boost::call_once(&amp;default_ctor::construct, constructed_); } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Joel de Guzman</dc:creator> <pubDate>Wed, 09 Jul 2008 14:43:31 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/1892#comment:2 https://svn.boost.org/trac10/ticket/1892#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket