这是重现问题的最少代码。唯一的外部先决条件是 pugixml.hpp 文件。
上下文是一个类,用于解析 XML 文件中的 id 引用(即,给定一个字符串值,找到其 id 属性设置为该值的节点)。我有一些包装 pugixml API 的帮助类,其中相关部分是这样的:
代理.h
#include "pugixml.hpp"
#include <algorithm>
#include <functional>
/**
* Adapter to strip away the xpath layer around a xml_node.
*/
template <typename Functor>
struct Shim
{
Functor& functor_;
Shim( Functor& functor )
: functor_(functor)
{}
void operator() ( pugi::xpath_node const& xpnode )
{
functor_( xpnode.node() );
}
};
class Agent
{
public:
explicit
Agent( std::string const& xpath )
: xpath_(xpath)
{}
// generic traverse over an xpath node_set
template <typename Handler >
size_t map( pugi::xml_node const& root, Handler& handler ) const
{
pugi::xpath_node_set _xpset(root.select_nodes( xpath_.c_str() ));
if ( _xpset.size() > 0 )
{
std::for_each( _xpset.begin(), _xpset.end(), Shim<Handler>(handler) );
}
return _xpset.size();
}
private:
std::string xpath_; // TODO: compile this into xpath_query?
};
#define XML_Node pugi::xml_node
我的 id 解析器类的第一个实现是这样的
IdNodeSet-Ah
#include "Agent.h"
#include <map>
class IdNodeSet
{
typedef std::map<char const*, XML_Node> NodeMap;
public:
IdNodeSet( XML_Node const& docRoot, XML_Node& defaultNode = XML_Node() )
: map_()
, default_(defaultNode)
{
Agent("//*[@id]").map( docRoot, *this );
}
void operator() ( XML_Node const& node )
{
map_[node.attribute("id").as_string()] = node;
}
XML_Node operator [] ( const char* id ) const
{
NodeMap::const_iterator _cit(map_.find( id ));
return _cit != map_.end() ? _cit->second : default_;
}
private:
NodeMap map_;
XML_Node default_;
};
这在 Cygwin g++ 3.4.4(cygming special,gdc 0.12,使用 dmd 0.125)中产生了以下错误:
IdNodeSet-A.h:29: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://cygwin.com/problems.html> for instructions.
这完全令人费解。
我唯一想到的是在构造函数中使用'*this'。但是使用辅助成员类进行修改:
IDNodeSet-Bh
#include "Agent.h"
#include <map>
class IdNodeSet
{
typedef std::map<char const*, XML_Node> NodeMap;
public:
IdNodeSet( XML_Node const& docRoot, XML_Node& defaultNode = XML_Node() )
: map_()
, helper_(map_)
, default_(defaultNode)
{
Agent("//*[@id]").map( docRoot, helper_ );
}
XML_Node operator [] ( const char* id ) const
{
NodeMap::const_iterator _cit(map_.find( id ));
return _cit != map_.end() ? _cit->second : default_;
}
private:
NodeMap map_;
struct Helper
{
Helper(NodeMap& map)
: map_(map)
{}
void operator() ( XML_Node const& node )
{
map_[node.attribute("id").as_string()] = node;
}
NodeMap& map_;
} helper_;
XML_Node default_;
};
产生相同的错误:
IdNodeSet-B.h:38: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://cygwin.com/problems.html> for instructions.
这不是火箭科学代码,那么是什么导致编译器核心转储?
更新: 预处理器输出(即来自 g++ -E)在这两种情况下编译都没有问题。所以这有资格作为一种可能的解决方法,但问题仍然存在:在解决方法不可行的情况下应该避免哪种代码?