2011-07-25 14 views
5

Tengo un problema un tanto extraño al intentar compilar algún código con la última versión de MinGW (GCC 4.5.2) en Windows Vista Home Premium 64 -poco. Al compilar este archivo, recibo un mensaje que dice que "cc1plus.exe ha dejado de funcionar" y la compilación falla sin mensaje de error. He intentado quitar el archivo hasta el mínimo absoluto que todavía produce el problema:"cc1plus.exe ha dejado de funcionar" al compilar el código de Boost Spirit

#include <boost/spirit/include/classic_file_iterator.hpp> 
#include <boost/spirit/include/classic_position_iterator.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
#include <boost/spirit/include/phoenix_fusion.hpp> 
#include <boost/spirit/include/phoenix_stl.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <vector> 

#define BOOST_SPIRIT_AUTO(domain_, name, expr)         \ 
    typedef boost::proto::result_of::           \ 
     deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type;     \ 
    BOOST_SPIRIT_ASSERT_MATCH(             \ 
     boost::spirit::domain_::domain, name##_expr_type);      \ 
    BOOST_AUTO(name, boost::proto::deep_copy(expr));       \ 

using namespace std; 

//This structure is used to determine the situation in which a certain tile sprite is used. 
struct TileCase { 
    //A vector of bit fields for which adjacent tiles which must be filled. 
    vector<unsigned> filled; 

    //A vector of bit fields for which adjacent tiles are optionally filled. 
    vector<unsigned> optionalFilled; 

    TileCase() : filled(0), 
        optionalFilled(0){} 
}; 

//Adapt the TileCase struct to a Fusion tuple. 
BOOST_FUSION_ADAPT_STRUCT (
    TileCase, 
    (std::vector<unsigned>, filled) 
    (std::vector<unsigned>, optionalFilled) 
) 

namespace qi = boost::spirit::qi; 
namespace phoenix = boost::phoenix; 
namespace ascii = boost::spirit::ascii; 
using phoenix::function; 
using ascii::space; 
using ascii::char_; 
using qi::eol; 

//A skipper rule for comments. 
BOOST_SPIRIT_AUTO(qi, comment, ("/*" >> *(char_ - "*/") >> "*/") 
           | ascii::space 
           | ("//" >> *(char_ - eol) >> eol) 
           ); 

//The Spirit error handler. 
struct error_handler_ { 
    template<typename, typename, typename> 
    struct result { typedef void type; }; 

    template <typename Iterator> 
    void operator()(
     qi::info const& what, 
     Iterator err_pos, Iterator last) const 
    { 
     //Get the line position. 
     boost::spirit::classic::file_position_base<string> const& pos = err_pos.get_position(); 

     //Throw an error. 
     stringstream error; 
     error << "Error! Expecting " 
       << what 
       << " at line " 
       << pos.line 
       << ", column " 
       << pos.column 
       << "!"; 
     throw(runtime_error(error.str())); 
    } 
}; 

function<error_handler_> const error_handler = error_handler_(); 

//The Spirit grammar for parsing tile data. 
template<typename Iterator> 
struct tileData : qi::grammar<Iterator, vector<TileCase>(), comment_expr_type> { 
    //The rule called when the parsing starts. 
    qi::rule<Iterator, vector<TileCase>(), comment_expr_type> start; 

    //The rule for parsing a single tile case. 
    qi::rule<Iterator, TileCase(), qi::locals<unsigned>, comment_expr_type> tile; 

    //The rule which parses yes/no/either bitflag blocks. 
    //Takes two references to unsigned, the first being the yes/no flag and the second being the optional flag. 
    qi::rule<Iterator, void(unsigned&, unsigned&), qi::locals<unsigned>, comment_expr_type> condBlock; 

    tileData() : tileData::base_type(start) { 
     using qi::eps; 
     using qi::lit; 
     using qi::on_error; 
     using qi::fail; 
     using qi::uint_; 
     using phoenix::at_c; 
     using phoenix::push_back; 
     using phoenix::resize; 
     using namespace qi::labels; 

     start = *tile[push_back(_val, _1)]; 

     tile = 
      //Parse the filled definition. 
      lit("filled") 

     > '(' 
      //Parse the generation to check for fills. 
     > uint_ 
      [ 
       _a = _1, 
       resize(at_c<0>(_val), _1 + 1), 
       resize(at_c<1>(_val), _1 + 1) 
      ] 
     > ')' 
      //Opening curly bracket for filled definition. 
     > '{' 
      //The condition block. 
     > condBlock 
      (
       //This one goes to filled[_a], 
       (at_c<0>(_val))[_a], 
       //and optionalFilled[_a]. 
       (at_c<1>(_val))[_a] 
      ) 
      //Closing curly bracket for filled definition. 
     > '}' 
     ; 

     condBlock = 
      eps 
      [_a = 1] 
     >> 
      (
      * (
        (
         +lit('+') 
         [_r1 += _a, _a *= 2] 
        ) 
       | 
        (
         +lit('*') 
         [_r2 += _a, _a *= 2] 
        ) 
       | 
        (
         +lit('-') 
         [_a *= 2] 
        ) 
       ) 
      ) 
     ; 

     on_error<fail> 
     (
      start, 
      error_handler(_4, _3, _2) 
     ); 
    } 
}; 


int main() { 
    try { 
     //Set up the file iterator. 
     typedef char char_type; 
     typedef boost::spirit::classic::file_iterator<char_type> iterator_type; 

     //Open the file. 
     iterator_type first("Test.txt"); 

     //Make sure the file is open. 
     if (!first) throw(runtime_error("Failed to open file!")); 

     //Find the end of the file. 
     iterator_type last = first.make_end(); 

     //Wrap the file iterator with a position iterator. 
     typedef boost::spirit::classic::position_iterator2<iterator_type> pos_iterator_type; 
     typedef tileData<pos_iterator_type> tileData; 
     pos_iterator_type pos_first(first, last, "Test.txt"); 
     pos_iterator_type pos_last; 

     //Prepare parsing information. 
     tileData tileData_parser; 
     vector<TileCase> cases; 

     //Parse the file. 
     if (phrase_parse(pos_first, pos_last, tileData_parser, comment, cases) && pos_first == pos_last) { 
      //Do something... 
     } 
    } 
    catch (const exception& e) { 
     cerr << "Exception while reading file:\n" << e.what() << endl; 
     return 1; 
    } 

    return 0; 
} 

En esta versión reducida, el compilador sólo se bloquea si se habilitan símbolos de depuración (-g). Sin embargo, con la versión completa del archivo, se bloquea independientemente. Además, si se elimina una parte del código de Spirit (como el controlador de errores o el patrón de comentarios), también se compila correctamente. Esto me sugiere que el compilador se está quedando sin memoria, pero no estoy del todo seguro de cómo solucionarlo.

He intentado construir directamente desde la línea de comandos y dentro de Code :: Blocks, pero cc1plus todavía se cuelga. La única bandera del compilador que he habilitado es -g. He verificado dos veces que solo tengo una instalación de MinGW, y he intentado reinstalarla, pero el problema persiste. ¿Qué estaría causando que esto suceda?

+0

Solo para risas, ¿qué hay de tratar de precompilar los encabezados? Boost ya es un monstruo, pero con Phoenix y Spirit debes incluir miles de encabezados ... –

+0

Dio un golpe. Ciertamente aceleró el tiempo de compilación, pero cc1plus aún se cuelga. ¡Gracias, sin embargo! – TheLastBanana

Respuesta

3

Este es un problema conocido con gcc/MingW, pero no sé cuál es el estado (si se ha reimprimido en absoluto, etc.) Alguien en la lista de correo Spirit propuso un parche que aumenta el tamaño de pila predeterminado para cc1plus.exe, al parecer solucionando el problema. Aunque no me he probado a mí mismo.

+0

No se ha corregido en mingw-w64 4.9.2 –

+0

Hola, @hkaiser, ¿puedes mostrar los enlaces n Lista de correo de Spirit sobre la solución? Está relacionado con el error de gcc http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56926, pero veo que alguien ha cambiado el valor de la pila, pero no solucionó este problema, ver: https://sourceforge.net/p/mingw-w64/mailman/message/30846624/, gracias – ollydbg23

0

Parece que hay un valor límite duro para el archivo PCH, que es aproximadamente 128M, ver mi reciente respuesta editado aquí: https://stackoverflow.com/a/19372020/154911 que estoy pidiendo, en el foro MinGW-W64 para ver si se puede construir una nueva cadena de herramientas para arreglar este problema

Cuestiones relacionadas