未定义的行为在某处提振精神:: ::气:: phrase_parse [英] undefined behaviour somewhere in boost::spirit::qi::phrase_parse

查看:174
本文介绍了未定义的行为在某处提振精神:: ::气:: phrase_parse的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习使用boost ::精神库。我把这个例子 HTTP://www.boost .ORG / DOC /库/ 1_56_0 /库/精神/例子/气/ num_list1.cpp 并编译它在我​​的电脑 - 它工作得很好。

但是,如果我修改了一点 - 如果我初始化解析器

 自动分析器=补气:: double_>> *(','>>气虚:: double_);

作为地方全局变量,并通过它来phrase_parse,一切都疯了。下面是完整的修改code(仅1行被修改,并加1) - http://pastebin.com/5rWS3pMt

如果我运行原来的code和通过3.14 3.15,以标准输入,它说,解析成功,但我的修改后的版本失败。我尝试了很多同类型的修改 - 分配解析器全局变量 - 在某些变种在某些编译器它出现segfaults

我不明白为什么和如何它是如此。
这里是另一个,更简单的版本,真正的打印,然后出现segfaults上铿锵++,只是出现segfaults在G ++

 的#include<升压/精神/有/ qi.hpp>#包括LT&;&iostream的GT;
#包括LT&;串GT;命名空间补气=的boost ::精神::补气;
命名空间ASCII =的boost ::精神:: ASCII;常量汽车doubles_parser_global =补气:: double_>> *(','>>气虚:: double_);诠释主(){
    常量汽车doubles_parser_local =补气:: double_>> *(','>>气虚:: double_);    常量标准::字符串NUMS {3.14,3.15,3.1415926};    性病::法院LT&;<的std :: boolalpha;    性病::法院
        <<齐:: phrase_parse(
            nums.cbegin(),nums.cend(),doubles_parser_local,ASCII ::空间
        )
        <<的std :: ENDL; //工作正常    性病::法院
        <<齐:: phrase_parse(
            nums.cbegin(),nums.cend(),doubles_parser_global,ASCII ::空间
        )//这个段错误
        <<的std :: ENDL;
}


解决方案

您不能使用汽车来的商店的解析器前$ P $pssions¹

要么你需要直接从临时前pression评估,或者您需要分配的规则/语法:

 常量齐::规则<的std ::字符串::为const_iterator,补气::空间类型> doubles_parser_local =补气:: double_>> *(','>>气虚:: double_);

您可以有你的蛋糕,吃它也对最新版本的BOOST(可能是Dev分支)应该有一个宏观BOOST_SPIRIT_AUTO

这正在成为一个有点FAQ项目:

我相信¹这实际上是底层原库的限制。有在github上,有望通过被完全重新设计,要知道引用来解决这些问题的始祖0X库版本(由Eric Niebler)。我想这需要一些C ++ 11的功能,提升原始目前无法使用。

I am learning to use boost::spirit library. I took this example http://www.boost.org/doc/libs/1_56_0/libs/spirit/example/qi/num_list1.cpp and compiled it on my computer - it works fine.

However if I modify it a little - if I initialize the parser itself

auto parser = qi::double_ >> *(',' >> qi::double_);

somewhere as global variable and pass it to phrase_parse, everything goes crazy. Here is the complete modified code (only 1 line is modified and 1 added) - http://pastebin.com/5rWS3pMt

If I run the original code and pass "3.14, 3.15" to stdin, it says Parsing succeeded, but with my modified version it fails. I tried a lot of modifications of the same type - assigning the parser to global variable - in some variants on some compilers it segfaults.

I don't understand why and how it is so. Here is another, simpler version which prints true and then segfaults on clang++ and just segfaults on g++

#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

const auto doubles_parser_global = qi::double_ >> *(',' >> qi::double_);

int main() {
    const auto doubles_parser_local = qi::double_ >> *(',' >> qi::double_);

    const std::string nums {"3.14, 3.15, 3.1415926"};

    std::cout << std::boolalpha;

    std::cout
        << qi::phrase_parse(
            nums.cbegin(), nums.cend(), doubles_parser_local, ascii::space
        )
        << std::endl;                             // works fine

    std::cout
        << qi::phrase_parse(
            nums.cbegin(), nums.cend(), doubles_parser_global, ascii::space
        )                                         // this segfaults
        << std::endl;
}

解决方案

You cannot use auto to store parser expressions¹

Either you need to evaluate from the temporary expression directly, or you need to assign to a rule/grammar:

const qi::rule<std::string::const_iterator, qi::space_type> doubles_parser_local = qi::double_ >> *(',' >> qi::double_);

You can have your cake and eat it too on most recent BOost versions (possibly the dev branch) there should be a BOOST_SPIRIT_AUTO macro

This is becoming a bit of a FAQ item:

¹ I believe this is actually a limitation of the underlying Proto library. There's a Proto-0x lib version on github (by Eric Niebler) that promises to solve these issues by being completely redesigned to be aware of references. I think this required some c++11 features that Boost Proto currently cannot use.

这篇关于未定义的行为在某处提振精神:: ::气:: phrase_parse的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆