2

我在使用 Boost 变体时遇到了问题。当变体被破坏时,我遇到了分段错误。

奇怪的是,只有当我没有激活编译器的优化(在我的例子中是 GCC)时,才会发生这种分段错误。例如,在 O1、O2、O3 模式下,我运行我的代码没有问题。

我的变体是这样定义的:

typedef boost::variant<
            ASTFunctionCall, 
            ASTSwap, 
            ASTDeclaration,
            ASTAssignment, 
            ASTIf,
            ASTWhile,
            ASTForeach,
            ASTFor>
        ASTInstruction;

变体的所有元素都是一些延迟的。Deferred 构造允许对象的延迟构造。这似乎是在访问其字段之一之前未构造该对象。真实对象由 shared_ptr 支持。

并且由于破坏了父级而发生了错误:

struct FunctionDeclaration { 
    std::shared_ptr<FunctionContext> context;
    std::string returnType;
    std::string functionName;
    std::string mangledName;
    std::vector<FunctionParameter> parameters;
    std::vector<ASTInstruction> instructions;
};

当指令向量被删除时,当变量的删除发生在这个特定的函数时,就会发生分段错误:

0x0000000000d71972 in boost::variant < eddic::Deferred < eddic::FunctionCall, std::shared_ptr < eddic::FunctionCall >>, eddic::Deferred >, eddic::Deferred < eddic::Declaration, std::shared_ptr < eddic::Declaration> >, eddic::Deferred < eddic::Assignment, std::shared_ptr < eddic::Assignment > >, eddic::Deferred < eddic::If, std::shared_ptr < eddic::If > > , eddic::Deferred < eddic::While, std::shared_ptr < eddic::While> >, eddic::Deferred < eddic::Foreach, std::shared_ptr < eddic::Foreach> >, eddic::Deferred < eddic::For, std::shared_ptr < eddic::For> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail ::variant::void_>::using_backup() const ()

编辑 2:删除 recursive_wrapper 和 intrusive_ptr 进行测试后,错误现在是 boost 的断言:Boost.Variant internal error: which out of range。

破坏变体是否有一些限制?就像我们不能放入变体中的某种类?

在此先感谢您提供与此问题相关的任何想法

编辑:它是否来自变体包含多次延迟、延迟、...的事实?

4

1 回答 1

1

我不确切知道您需要什么语义,但是您能否像这样简化变体结构树:

typedef boost::variant<
        ASTFunctionCall, 
        ASTSwap, 
        ASTDeclaration,
        ASTAssignment, 
        boost::recursive_wrapper<
            boost::variant<ASTIf, ASTWhile, ASTForeach, ASTFor> >
    ASTInstruction;

?

于 2011-11-10T13:23:28.207 回答