【问题标题】:Internal compiler error with Boost.SpiritBoost.Spirit 的内部编译器错误
【发布时间】:2012-07-17 20:57:45
【问题描述】:

我正在尝试使用 GCC 3.4.6 和 Boost 1.43 编译以下看似简单的代码,它会产生内部编译器错误:

#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>

namespace lex    = boost::spirit::lex;
namespace qi     = boost::spirit::qi;

typedef lex::lexertl::token<std::string::iterator> TokenT;
typedef lex::lexertl::actor_lexer<TokenT> LexerT;

template <typename LexerT>
struct Tokens: public lex::lexer<LexerT>
{};

int main()
{
   typedef Tokens<LexerT>::iterator_type IteratorT;
   qi::rule<IteratorT, int> expression;

   expression = (qi::int_ >> qi::int_) [ qi::_val = qi::_1 ];
}

生成的错误:

.../boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:83: internal compiler error: in lookup_member, at cp/search.c:1300

main() 的最后一行产生了这个错误。通过让expression 规则在std::string::iterator 而不是IteratorT 上工作,此错误就会消失。

非常感谢您在使用词法分析器的同时修复错误的任何帮助。

谢谢!

【问题讨论】:

  • 首先...获得更新的编译器。这是cygwin吗?使用 mingw,链接:mingw-w64.sourceforge.net64bit32bit 此处为 4.7.1)
  • 当前 GCC 是 4.7.1。 3.4.6 版非常非常旧(大约 2006 年 3 月)。
  • 我知道这是一个旧的编译器,但这是我工作场所的构建环境支持的最新版本,所以我别无选择!顺便说一句:我对这个问题做了一些修改。它似乎与延迟函数对象无关。是词法分析器!
  • 什么编译环境只支持GCC 3.4.6?我所知道的没有实际的 build 环境。
  • 我猜这与构建环境无关(在我们的案例中是内部构建的)。更多的是关于我们支持的平台(RHEL 3 和 4)以及它们上可用的默认编译器和 C 库。说到生意,你知道生活并不理想:)

标签: gcc boost-spirit boost-spirit-qi gcc3 boost-spirit-lex


【解决方案1】:

你错过了括号:

qi::rule<IteratorT, int()> expression;

这可能会修复编译错误(虽然我无法检查,因为 gcc、clang 和 msvc 都愉快地编译了它)


您可能希望减少编译器压力:

  • 增加可用内存
  • 降低限制(见下文)
  • 禁用调试信息(-g0)
  • 和优化(-O0;或者,针对大小进行优化 -Os)

该地区可能更多。

限制

我做了一个简单的

grep -EoRh '\<\w+_LIMIT\>' ~/custom/boost_1_50_0/boost/spirit/home/ -h | sort -u

获取可能的定义列表,并基于它进行以下更改:

#ifdef LEAN
#define PHOENIX_ACTOR_LIMIT      3 // boost 1_50 default: 10
#define PHOENIX_ARG_LIMIT        5 // boost 1_50 default: 10
#define PHOENIX_CATCH_LIMIT      1 // boost 1_50 default:  9
#define PHOENIX_COMPOSITE_LIMIT  5 // boost 1_50 default: 10
#define PHOENIX_DYNAMIC_LIMIT    1 // boost 1_50 default: 10
#define PHOENIX_LIMIT            5 // boost 1_50 default: 10
#define PHOENIX_LOCAL_LIMIT      3 // boost 1_50 default: 10
#define PHOENIX_MEMBER_LIMIT     3 // boost 1_50 default:  8
#define SPIRIT_ARGUMENTS_LIMIT   5 // boost 1_50 default: 10
#define SPIRIT_ATTRIBUTES_LIMIT  5 // boost 1_50 default: 10
#endif

#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace lex    = boost::spirit::lex;
namespace qi     = boost::spirit::qi;
namespace phx    = boost::phoenix;

struct funcImpl
{
   template <typename T>
   struct result { typedef int type; };

   template <typename T>
   int operator()(T& x) const {
      return 0;
   }
};

typedef lex::lexertl::token<std::string::iterator> TokenT;
typedef lex::lexertl::actor_lexer<TokenT> LexerT;

template <typename LexerT>
struct Tokens: public lex::lexer<LexerT>
{};

int main()
{
   //typedef Tokens<LexerT>::iterator_type IteratorT;
   typedef char* IteratorT;
   qi::rule<IteratorT, int()> expression;

   phx::function<funcImpl> func = funcImpl();
   expression = (qi::int_ >> qi::int_) [ qi::_val = func(qi::_1) ];


   std::cout   << "#define PHOENIX_ACTOR_LIMIT "                       << PHOENIX_ACTOR_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_ARG_LIMIT "                         << PHOENIX_ARG_LIMIT                         << '\n';
   std::cout   << "#define PHOENIX_CATCH_LIMIT "                       << PHOENIX_CATCH_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_COMPOSITE_LIMIT "                   << PHOENIX_COMPOSITE_LIMIT                   << '\n';
   std::cout   << "#define PHOENIX_DYNAMIC_LIMIT "                     << PHOENIX_DYNAMIC_LIMIT                     << '\n';
   std::cout   << "#define PHOENIX_LIMIT "                             << PHOENIX_LIMIT                             << '\n';
   std::cout   << "#define PHOENIX_LOCAL_LIMIT "                       << PHOENIX_LOCAL_LIMIT                       << '\n';
   std::cout   << "#define PHOENIX_MEMBER_LIMIT "                      << PHOENIX_MEMBER_LIMIT                      << '\n';
   std::cout   << "#define SPIRIT_ARGUMENTS_LIMIT "                    << SPIRIT_ARGUMENTS_LIMIT                    << '\n';
   std::cout   << "#define SPIRIT_ATTRIBUTES_LIMIT "                   << SPIRIT_ATTRIBUTES_LIMIT                   << '\n';
   //std::cout << "#define BOOST_PHOENIX_LIMIT "                       << BOOST_PHOENIX_LIMIT                       << '\n';
   //std::cout << "#define BOOST_SPIRIT_CLOSURE_LIMIT "                << BOOST_SPIRIT_CLOSURE_LIMIT                << '\n';
   //std::cout << "#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT " << BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT << '\n';
   //std::cout << "#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT "       << BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT       << '\n';
   //std::cout << "#define BOOST_SPIRIT_SELECT_LIMIT "                 << BOOST_SPIRIT_SELECT_LIMIT                 << '\n';
   //std::cout << "#define BOOST_SPIRIT_SWITCH_CASE_LIMIT "            << BOOST_SPIRIT_SWITCH_CASE_LIMIT            << '\n';
   //std::cout << "#define PHOENIX_CONSTRUCT_LIMIT "                   << PHOENIX_CONSTRUCT_LIMIT                   << '\n';
   //std::cout << "#define SPIRIT_CLOSURE_LIMIT "                      << SPIRIT_CLOSURE_LIMIT                      << '\n';
}

现在,发生以下大小变化(在 LoC 预处理中):

sehe@mint12:/tmp$ g++ -g0 -O0 -I /home/sehe/custom/boost_1_50_0/ test.cpp -E | wc -l
193011
sehe@mint12:/tmp$ g++ -g0 -O0 -I ./boost_1_43_0/ test.cpp -DLEAN -E | wc -l
168862

基本上,代码行数减少了 >10%。它可能会有所帮助。

【讨论】:

  • 感谢您的建议。不幸的是,它不能解决它!
  • @HaithamGad 我添加了一些提示/调整,可能帮助您通过编译器。我仍然认为您应该使用更新的编译器。无论如何,没有平台支持 GNU 3.4。在本地目录中提取 tarball 并从那里使用二进制文件并不难。 IME,这通常适用于嵌入式系统到 AIX、Solaris 等:gcc.gnu.org/install/binaries.html
  • 谢谢赛斯。我在家里使用较新的编译器,并在上面编译了我的代码,但是当我在工作场所尝试该版本时,它不断出现故障。问题是,我们在 RedHat Enterprise Linux 3 和 4 上发布我们的产品,这是这些古老平台上的默认编译器版本。我试过你的代码,但它仍然打破。无论如何,不​​要紧。我认为这与词法分析器的使用、排序运算符和语义操作的使用的组合有关。我会尝试调整代码,直到它编译为止。
  • 我把所有的错误都贴在这里,以防任何人都能破译其中的任何一个:pastebin.com/BMPCSUzc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多