c++ - What debugging technique for a karma generator with runtime error -
not easy sate programming question don't see problem is. indeed, have runtime error lost somewhere in boost spirit karma library. guess miss debugging technique here.
i have seen macro boost_spirit_debug_node(s) helps parsers, although couldn't find reference in manual. generators, seems not working , (honestly) don't have courage (should ?) dig code of library understand issue is.
i have tried generate 3 types of union-like structure alone in grammar without issue. assume error comes cast of u structure boost variant, again (see casting attribute boost::variant) have no proof.
for solve simple code inspection, here minimal example of issue:
#include <iostream> #include <fstream> #include <vector> #include <iterator> //#define boost_spirit_debug #include <boost/spirit/include/karma.hpp> #include <boost/variant/variant.hpp> namespace ka = boost::spirit::karma; typedef std::back_insert_iterator<std::string> iterator; typedef enum {a, b, c } e; typedef enum {foo, bar, pointer } k; struct u /* union */ { k kind; double foo; e bar; unsigned int * p; }; class ename : public ka::symbols<e, std::string> { public: ename() { add (a,"a") (b,"b") (c,"c"); } }; typedef boost::variant<e, double, unsigned int *> uvariant; namespace boost { namespace spirit { namespace traits { template<> struct transform_attribute<const u,uvariant,ka::domain> { typedef uvariant type; static type pre(const u & u) { switch (u.kind) { case foo: return type(u.foo); case bar: return type(u.bar); case pointer: return type(u.p); } return type(a); } }; }}} class grm: public ka::grammar<iterator, u()> { public: grm():grm::base_type(start) { start = ka::attr_cast<uvariant >(bar | foo | pointer); bar = b; foo = ka::double_; pointer = ka::hex; } private: ka::rule<iterator,u()> start; ka::rule<iterator,double()> foo; ka::rule<iterator,e()> bar; ka::rule<iterator,unsigned int *()> pointer; ename b; }; int main(int argc, char * argv[]) { grm g; u u; //unsigned int a; u.kind = bar; //u.foo = 1.0; u.bar = b; //u.p = &a; std::string generated; std::back_insert_iterator<std::string> sink(generated); ka::generate(sink,g,u); std::cout << generated; return 0; }
update: compiler: visual c++ express version 11 , 12. call stack stops @ :
// if seeing compilation error here stating // third parameter can't converted karma::reference // trying use rule or grammar // incompatible delimiter type. if (f(sink, context, delim)) // <--- call stack stops here (last boost spirit reference)
also have found out definition of _scl_secure_no_warnings macro shadowed following compiler warning:
warning c4996: 'std::_copy_impl': function call parameters may unsafe - call relies on caller check passed values correct. disable warning, use -d_scl_secure_no_warnings. see documentation on how use visual c++ 'checked iterators'
this warning referring several boost-spirit files:
- spirit\home\karma\detail\output_iterator.hpp(242)
spirit\home\karma\detail\output_iterator.hpp(577)
spirit\home\karma\detail\output_iterator.hpp(574)
spirit\home\karma\detail\alternative_function.hpp(170)
spirit\home\karma\detail\alternative_function.hpp(162)
spirit\home\karma\operator\alternative.hpp(122)
spirit\home\karma\auxiliary\attr_cast.hpp(85)
spirit\home\karma\nonterminal\detail\generator_binder.hpp(43)
spirit\home\karma\nonterminal\detail\generator_binder.hpp(52)
spirit\home\karma\nonterminal\rule.hpp(193)
spirit\home\karma\nonterminal\rule.hpp(230)
i can't reproduce error.
i can't "solve it" little code inspection either. can 2 things:
i can confirm debug macros don't appear implemented karma
i can go out on limb , perhaps
bar|foo|pointer
needs deep-copied:start = ka::attr_cast<uvariant >(boost::proto::deep_copy(bar | foo | pointer));
i tried ub-sanitizer , address-sanitizer enabled, both didn't report problems.
update in fact looks can "solve" little code inspection (and lucky brainwave) after all:
in fact, running under valgrind show a problem , indeed, goes away when adding deep_copy
.
i'll add references how hypothesized these things:
in general: problem dangling references temporaries in (proto) expression templates
specifically problem seen years ago in
qi::attr_cast<>
:- this comment jan 2014: syntax tree empty nodes issue spirit qi minic example
Comments
Post a Comment