提升精神V2 与优化级别相关的气错误 [英] boost spirit V2 qi bug associated with optimization level

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

问题描述

我在业余时间开发我的代码.最好在调试模式下.最近,当我尝试构建发布版本时,我得到了错误(运行时,输出:1 2 然后失败).我找到了包含错误的一段代码(如下),我发现只有在优化级别为 -Os、-Ofast、-O2、-O3 而不是 <代码>-O、-O0、-O1、-Og.在发布模式下,我的调试能力受到限制.错误的原因是什么?发现此类错误的方法是什么?

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 2 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?

#!/usr/bin/env bash -vex WARN="-W -Wall -Wextra" INCLUDE="-isystem/c/libs/boost-trunk" OPT="-O2" g++ -x c++ - -std=gnu++1y $INCLUDE

#!/usr/bin/env bash -vex WARN="-W -Wall -Wextra" INCLUDE="-isystem /c/libs/boost-trunk" OPT="-O2" g++ -x c++ - -std=gnu++1y $INCLUDE

$WARN $OPT -o <<__EOF &&./a &&echo -e "e[1;32msucceedede[0m" ||echo -e "e[1;31mfailede[0m"

$WARN $OPT -o a <<__EOF && ./a && echo -e "e[1;32msucceedede[0m" || echo -e "e[1;31mfailede[0m"

#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+|(/*[^*]**+([^/*][^*]**+)*/)|(//[^
]*))"
    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.

最重要的是表达式模板(例如 Boost Proto 使用的模板,因此也被 Boost Spirit 使用).它们仅在其封闭的完整表达式的末尾有效 [1]

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 [1]

典型的解决方法是:

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

你可以在这里找到它:http://svn.boost.org/svn/boost/trunk/libs/spirit/example/qi/typeof.cpp,它首先在这篇博文的评论中被介绍:http://boost-spirit.com/home/articles/qi-example/2 秒内从零到 60 英里/小时/

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/

我测试的显式修复(在我的盒子上运行良好,valgrind 中没有警告):

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 承诺去除这个疣.有点相关,我认为 Protox11 也通过始终了解引用来消除这个问题.

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

[1] Grep 延长临时工寿命的标准.表达式模板保留对所使用的文字的引用(其余的仍然具有值语义),但临时对象不绑定到 (const) 引用.所以他们超出了范围.未定义行为结果

[1] 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 与优化级别相关的气错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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