деструкторы варианта буста приводят к ошибке сегментации - PullRequest
2 голосов
/ 10 ноября 2011

Я столкнулся с проблемой при использовании варианта Boost. У меня ошибка сегментации, когда вариант разрушается.

Странная вещь заключается в том, что эта ошибка сегментации возникает только тогда, когда я не активирую оптимизации компилятора (GCC в моем случае). Например, в режиме O1, O2, O3 у меня нет проблем с запуском моего кода.

Мой вариант определен так:

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

Все элементы варианта являются отложенными. Отложенная конструкция включает отложенное построение объектов. Кажется, что объект не создан до того, как появится доступ к одному из его полей. Реальный объект поддерживается с 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 в boost :: варианте >, eddic :: Deferred>, eddic :: Deferred >, eddic :: Deferred >, eddic :: Deferred >, eddic :: Deferred >, eddic :: Deferred >, eddic: : Deferred >, boost :: detail :: option :: void_, boost :: detail :: option :: void_, boost :: detail :: option:: : void_, Boost :: Detail :: Вариант :: void_, Boost :: Detail :: Вариант :: void_, Boost :: Detail :: Вариант :: void_, Boost :: Detail :: Вариант :: void_, Boost :: деталь :: вариант :: void_, Boost :: деталь :: вариант :: void_, Boost :: деталь :: вариант :: void_, Boost :: деталь :: вариант :: void_, Boost :: деталь :: Вариант :: void _> :: using_backup () const ()

РЕДАКТИРОВАТЬ 2: После удаления recursive_wrapper и intrusive_ptr для проверки, ошибка теперь является подтверждением boost: Boost.Variant внутренняя ошибка: которая выходит за пределы диапазона.

Есть ли ограничения по варианту разрушений? Как какие-то классы, которые мы не можем поместить в вариант?

Заранее спасибо за любую идею, касающуюся этой проблемы

РЕДАКТИРОВАТЬ: Может это происходит из-за того, что вариант содержит несколько раз Отложено, Отложено, ...?

1 Ответ

1 голос
/ 10 ноября 2011

Я не знаю точно, какая семантика вам нужна, но не могли бы вы упростить дерево структуры вариантов следующим образом:

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

?

...