C++ 增压变量析构函数导致分段故障

C++ 增压变量析构函数导致分段故障,c++,gcc,boost,segmentation-fault,boost-variant,C++,Gcc,Boost,Segmentation Fault,Boost Variant,我在使用增压变型时遇到了一个问题。当变体被破坏时,我有一个分段错误 奇怪的是,这种分段错误只有在我没有激活编译器的优化时才会发生(在我的例子中是GCC)。例如,在O1、O2、O3模式下,我运行代码没有问题 我的变体定义如下: typedef boost::variant< ASTFunctionCall, ASTSwap, ASTDeclaration, ASTAssignment,

我在使用增压变型时遇到了一个问题。当变体被破坏时,我有一个分段错误

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

我的变体定义如下:

typedef boost::variant<
            ASTFunctionCall, 
            ASTSwap, 
            ASTDeclaration,
            ASTAssignment, 
            ASTIf,
            ASTWhile,
            ASTForeach,
            ASTFor>
        ASTInstruction;
typedef boost::variant<
打电话,
ASTSwap,
声明,
A分配,
阿斯蒂夫,
与此同时,
阿斯特弗雷赫,
ASTFor>
阅读教学;
变体的所有元素都是延迟的。延迟构造启用对象的延迟构造。这似乎是在访问对象的某个字段之前没有构造对象。真实对象由共享的\u 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;
};
struct FunctionDeclaration{
std::共享的ptr上下文;
std::字符串返回类型;
std::字符串函数名;
std::字符串mangledName;
std::向量参数;
向量指令;
};
当指令向量被删除时,当在该特定功能中删除变量时,会发生分段错误:

boost::variant>,eddic::Deferred>,eddic::Deferred>,eddic::deferreded>、eddic::Deferred、eddic::Deferred、std::shared\u ptr、boost::detail::variant::Vantal::void、boost::detail::variant::Vantal::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\u>::使用

编辑2:删除要测试的递归_包装器和侵入性_ptr后,错误现在是boost:boost的断言。Variant internal error:超出范围

对于破坏变量是否有一些限制?像一些我们不能放在变体中的类

提前感谢您提出与此问题相关的任何想法


编辑:它是否可能来自变量多次包含延迟、延迟

我不知道您需要什么样的语义,但您能否将变体结构树简化为:

typedef boost::variant<
        ASTFunctionCall, 
        ASTSwap, 
        ASTDeclaration,
        ASTAssignment, 
        boost::recursive_wrapper<
            boost::variant<ASTIf, ASTWhile, ASTForeach, ASTFor> >
    ASTInstruction;
typedef boost::variant<
打电话,
ASTSwap,
声明,
A分配,
递归包装器<
boost::variant>
阅读教学;

我的直觉确实是递归包装器对于树递归变量类型的测试不太好。您可以在测试套件中检查它是否是测试覆盖范围的一部分。草书包装不在原因中。事实上,我完全删除了它,因为Deferred也给了我使用未完全定义的类型的可能性(Deferred动态分配对象)?如果这能解决问题,我将采用它,但我将不得不重写我所有的访问者。我只是尝试了一下,但我有一些转换错误,不仅仅是访问者。@ BaptisteWicht:说实话,我会认为这是一个错误解决办法。再说一次,我以前从未见过“多重递归”变体,所以也许有一个比我聪明得多的人可以解释这是否(im)可能和可能why@BaptisteWicht:您能否使用此解决方法单独检查“析构函数”问题是否没有发生?如果它不改变任何事情,你可以不遗余力。另外,如果它真的“修复”了析构函数问题,我建议在上发布一篇博学的bug评论,我删除了递归_包装,所以问题就出在这一部分。@Baptistewich:我非常感兴趣的是它的后果(你是如何使用Deferred的)以及你是否觉得它是一个bug(值得报告)