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