Opened 14 years ago
Closed 14 years ago
#1892 closed Bugs (fixed)
boost::spirit::static_ causes link error (using wave)
Reported by: | anonymous | Owned by: | Joel de Guzman |
---|---|---|---|
Milestone: | Boost 1.36.0 | Component: | spirit |
Version: | Boost 1.35.0 | Severity: | Regression |
Keywords: | Cc: |
Description
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.
The link error text is (vs2005):
1>token_output.obj : error LNK2005: "public: thiscall public: __thiscall boost::spirit::static_<class boost::thread_specific_ptr<class boost::weak_ptr<struct boost::spirit::impl::grammar_helper<struct boost::spirit::grammar<class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context<struct boost::spirit::nil_t> >,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner<char const *,struct boost::spirit::scanner_policies<struct boost::spirit::skipper_iteration_policy<struct boost::spirit::iteration_policy>,struct boost::spirit::match_policy,struct boost::spirit::action_policy> > > > >,class boost::spirit::impl::get_definition_static_data_tag>::static_<class boost::thread_specific_ptr<class boost::weak_ptr<struct boost::spirit::impl::grammar_helper<struct boost::spirit::grammar<class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context<struct boost::spirit::nil_t> >,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner<char const *,struct boost::spirit::scanner_policies<struct boost::spirit::skipper_iteration_policy<struct boost::spirit::iteration_policy>,struct boost::spirit::match_policy,struct boost::spirit::action_policy> > > > >,class boost::spirit::impl::get_definition_static_data_tag>(class boost::spirit::impl::get_definition_static_data_tag)'::
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>token_output.obj : error LNK2005: "public: static void cdecl public: __thiscall boost::spirit::static_<class boost::thread_specific_ptr<class boost::weak_ptr<struct boost::spirit::impl::grammar_helper<struct boost::spirit::grammar<class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context<struct boost::spirit::nil_t> >,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner<char const *,struct boost::spirit::scanner_policies<struct boost::spirit::skipper_iteration_policy<struct boost::spirit::iteration_policy>,struct boost::spirit::match_policy,struct boost::spirit::action_policy> > > > >,class boost::spirit::impl::get_definition_static_data_tag>::static_<class boost::thread_specific_ptr<class boost::weak_ptr<struct boost::spirit::impl::grammar_helper<struct boost::spirit::grammar<class boost::wave::util::time_conversion::time_conversion_grammar,struct boost::spirit::parser_context<struct boost::spirit::nil_t> >,class boost::wave::util::time_conversion::time_conversion_grammar,class boost::spirit::scanner<char const *,struct boost::spirit::scanner_policies<struct boost::spirit::skipper_iteration_policy<struct boost::spirit::iteration_policy>,struct boost::spirit::match_policy,struct boost::spirit::action_policy> > > > >,class boost::spirit::impl::get_definition_static_data_tag>(class boost::spirit::impl::get_definition_static_data_tag)'::
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
Attachments (1)
Change History (3)
by , 14 years ago
Attachment: | reproduce1892.zip added |
---|
comment:1 by , 14 years ago
Proposed fix:
Move the definitions of the "destructor" and "default_constructor" out of static_'s ctor body, and put them inside the class template definition instead.
A patch against Boost release 1.35 of /boost/spirit/core/non_terminal/impl/static.hpp gives:
@@ -40,20 +40,15 @@ struct static_ : boost::noncopyable { - typedef T value_type; - typedef typename boost::call_traits<T>::reference reference; - typedef typename boost::call_traits<T>::const_reference const_reference; - - static_(Tag = Tag()) - { - struct destructor + private: + struct destructor { ~destructor() { static_::get_address()->~value_type(); } }; - + struct default_ctor { static void construct() @@ -63,6 +58,13 @@ } }; + public: + typedef T value_type; + typedef typename boost::call_traits<T>::reference reference; + typedef typename boost::call_traits<T>::const_reference const_reference; + + static_(Tag = Tag()) + { boost::call_once(&default_ctor::construct, constructed_); }
comment:2 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Source files to reproduce the link errors