"cc1plus.exe has stopped working" while compiling Boost Spirit code
I'm having a bit of an odd problem while trying to compile some code using the latest version of MinGW (GCC 4.5.2) under Windows Vista Home Premium 64-bit. While compiling this file, I get a message that "cc1plus.exe has stopped working" and the compilation fails with no error message. I have attempted to strip the file down to the absolute bare minimum that still produces the problem:
#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::开发者_如何学Crule<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;
}
In this stripped-down version, the compiler only crashes if debugging symbols (-g) are enabled. However, with the full version of the file, it crashes regardless. As well, if a portion of the Spirit code is removed (such as the error handler, or the comment skipper), it also compiles correctly. This suggests to me that the compiler is running out of memory, but I'm not entirely sure how to fix it.
I have tried building directly from command-line as well as from within Code::Blocks, but cc1plus still crashes. The only compiler flag I have enabled is -g. I have double-checked that I only have one installation of MinGW, and I have tried re-installing it, but the problem persists. What would be causing this to happen?
This is a known problem with gcc/MingW, but I don't know what the status is (whether it has been reproted at all, etc.) Somebody on the Spirit mailing list proposed a patch increasing the default stack size for cc1plus.exe, reportedly fixing the problem. I have not tried myself, though.
It looks like there is a hard limit value for the pch file, which is about 128M, see my recent edited answer here: https://stackoverflow.com/a/19372020/154911 I'm asking in mingw-w64 forum to see whether they can build a new toolchain to fix this issue.
精彩评论