本文介绍了提升精神V2 qi与优化级别相关的bug的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我在业余时间开发自己的代码。最好在调试模式下。最近,当我试图构建发行版时,我得到了错误(运行时,输出: 1 \\\
2\\\
然后失败)。我找到了一段代码(下面),其中包含错误,并且我发现错误只发生在优化级别 -Os,-Ofast,-O2,-O3 但不是 -O,-O0,-O1,-Og 。在发布模式下,我受限于调试功能。错误的原因是什么?
$ b



  #include< iterator> 
#include< string>
#include< iostream>

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

使用命名空间boost :: spirit;

模板< typename Iterator>
struct skipper
:qi :: grammar<迭代器>
{

skipper();

private:

typename skipper :: base_type :: start_type skipper_;

};

模板< typename Iterator>
船长< Iterator> :: skipper()
:skipper :: base_type(skipper_,skipper)
{
std :: cerr<< 1<<的std :: ENDL;
auto const ana =
*〜qi :: char _('*')> + qi :: char _('*')
;
std :: cerr<< 2<<的std :: ENDL;
skipper_ =
qi :: space
| (/ *> ana> *(〜qi :: char _(/ *)> ana)>'/')
| (//> *(qi :: char_-qi :: eol)>(qi :: eol | qi :: eoi))
; // R(\s + |(\ / \ * [^ *] * \ * +([^ / *] [^ *] * \ * +)* \ /)|(\ / \ / [^ \r\\\
] *))
std :: cerr<< 3<的std :: ENDL;
}

using input_type = std :: string;
使用input_iterator_type = std :: istreambuf_iterator< typename input_type :: value_type>;
使用base_iterator_type = multi_pass< input_iterator_type>;

模板struct skipper< base_iterator_type>;

使用skipper_type = skipper< base_iterator_type>;

int main()
{
skipper_type const skipper_;
std :: cerr<< 4<<的std :: ENDL;
返回EXIT_SUCCESS;
}
__EOF

gcc -v 2> & 1 | tail -n1

  gcc版本4.8.1(rev5,由MinGW-W64项目构建) 


解决方案

这是您代码中的错误,编译器或优化级别。



Cinch带有表达式模板(与Boost Proto使用的模板类似,也就是Boost Spirit)。它们 仅在它们的封闭式表达式结尾有效



规范的工作方式是:

$ p $ BOOST_SPIRIT_AUTO(ana,*〜qi :: char _('*')> + qi:的:char _( '*'));

你可以在这里找到它:,它首先在这篇博文的评论中介绍: p>

我测试过的显式修正(在我的盒子上很好地工作,valgrind中没有任何警告):

  auto const ana = boost :: proto :: deep_copy(
*〜qi :: char _('*')> + qi :: char _('*'))
;

Spirit X3承诺消除这种疣。略有相关,我认为Protox11通过在任何时候都意识到引用而消除了这个问题。




修改临时对象延长寿命的标准。表达式模板保持对所使用的文字的引用(其余部分具有值语义),但临时文件不会绑定到(const)引用。所以他们超出了范围。 结果


I develop my code in my spare time. Preferably in debug mode. Recently, when I tried to build release version, then I got the error (runtime, output: 1\n2\n then failure). I located the piece of code (below), which contains the error, and I found, that the error only occurs, when optimization level is -Os, -Ofast, -O2, -O3 but not -O, -O0, -O1, -Og. In release mode I am constrained in debug abilities. What is the cause of the error? What is the method to find such errors?

#include <iterator>
#include <string>
#include <iostream>

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

using namespace boost::spirit;

template< typename Iterator >
struct skipper
        : qi::grammar< Iterator >
{

    skipper();

private :

    typename skipper::base_type::start_type skipper_;

};

template< typename Iterator >
skipper< Iterator >::skipper()
    : skipper::base_type(skipper_, "skipper")
{
    std::cerr << 1 << std::endl;
    auto const ana =
            *~qi::char_('*') > +qi::char_('*')
            ;
    std::cerr << 2 << std::endl;
    skipper_ =
            qi::space
            | ("/*" > ana > *(~qi::char_("/*") > ana) > '/')
            | ("//" > *(qi::char_ - qi::eol) > (qi::eol | qi::eoi))
            ; // R"(\s+|(\/\*[^*]*\*+([^/*][^*]*\*+)*\/)|(\/\/[^\r\n]*))"
    std::cerr << 3 << std::endl;
}

using input_type = std::string;
using input_iterator_type = std::istreambuf_iterator< typename input_type::value_type >;
using base_iterator_type = multi_pass< input_iterator_type >;

template struct skipper< base_iterator_type >;

using skipper_type = skipper< base_iterator_type >;

int main()
{
    skipper_type const skipper_;
    std::cerr << 4 << std::endl;
    return EXIT_SUCCESS;
}
__EOF

gcc -v 2>&1 | tail -n1:

gcc version 4.8.1 (rev5, Built by MinGW-W64 project)
解决方案

It's a bug in your code, nothing wrong with the compiler or the optimization levels.

The cinch is with expression templates (like the ones used by Boost Proto, and hence by Boost Spirit). They are only valid to the end of their enclosing full expression

The canonical workaound is:

 BOOST_SPIRIT_AUTO(ana, *~qi::char_('*') > +qi::char_('*'));

You can find it here: http://svn.boost.org/svn/boost/trunk/libs/spirit/example/qi/typeof.cpp and it got first introduced in the comments at this blog post: http://boost-spirit.com/home/articles/qi-example/zero-to-60-mph-in-2-seconds/

The explicit fix I tested (which worked nicely on my box, no warnings remaining in valgrind):

auto const ana = boost::proto::deep_copy(
        *~qi::char_('*') > +qi::char_('*'))
        ;

Spirit X3 promises to remove this wart. Slightly related, I think Protox11 also removes this issue by being aware of references at all times.


Grep the standard for lifetime extension of temporaries. The expression templates keep references to the literals used (the rest has value semantics anyways), but the temporaries aren't bound to (const) references. So they go out of scope. Undefined Behaviour results

这篇关于提升精神V2 qi与优化级别相关的bug的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 10:18