boost spirit V2 qi error asociado con el nivel de optimización

Desarrollo mi código en mi tiempo libre. Preferiblemente en modo de depuración. Recientemente, cuando intenté construir la versión de lanzamiento, obtuve el error (tiempo de ejecución, salida: 1\n2\n luego fallo). Localicé el fragmento de código (a continuación), que contiene el error, y encontré que el error solo ocurre cuando el nivel de optimización es -Os, -Ofast, -O2, -O3 pero no -O, -O0, -O1, -Og . En el modo de lanzamiento, estoy limitado en las capacidades de depuración. ¿Cuál es la causa del error? ¿Cuál es el método para encontrar tales errores?

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

$ WARN $ OPT -oa << __ EOF && ./a && echo -e "\ e [1; 32msucceeded \ e [0m" || echo -e "\ e [1; 31mfailed \ e [0m"]

 #include  #include  #include  #include  #include  using namespace boost::spirit; template struct skipper : qi::grammar { skipper(); private : typename skipper::base_type::start_type skipper_; }; template skipper::skipper() : skipper::base_type(skipper_, "skipper") { std::cerr << 1 < +qi::char_('*') ; std::cerr << 2 < 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; using base_iterator_type = multi_pass; template struct skipper; using skipper_type = skipper; int main() { skipper_type const skipper_; std::cerr << 4 << std::endl; return EXIT_SUCCESS; } __EOF 

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

 gcc version 4.8.1 (rev5, Built by MinGW-W64 project) 

Es un error en su código, nada de malo con el comstackdor o los niveles de optimización.

La cincha es con plantillas de expresión (como las utilizadas por Boost Proto, y por lo tanto por Boost Spirit). Solo son válidos hasta el final de su expresión completa adjunta [1]

El trabajo canónico es:

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

Puede encontrarlo aquí: http://svn.boost.org/svn/boost/trunk/libs/spirit/example/qi/typeof.cpp y se presentó por primera vez en los comentarios en esta publicación del blog: http: // boost-spirit.com/home/articles/qi-example/zero-to-60-mph-in-2-seconds/

La solución explícita que probé (que funcionó bien en mi caja, no hay advertencias restantes en valgrind):

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

Spirit X3 promete eliminar esta verruga. Ligeramente relacionado, creo que Protox11 también elimina este problema al estar al tanto de las referencias en todo momento.


[1] Amplia el estándar para la extensión de por vida de los temporales. Las plantillas de expresión mantienen referencias a los literales utilizados (el rest tiene semántica de valores de todos modos), pero los temporales no están vinculados a (const) referencias. Entonces salieron del scope. Comportamiento indefinido resultados