2010-08-09 5 views
4

У меня создалось впечатление, что использование setjmp() и longjmp() в C++ почти гарантировало испортить стек, поскольку эти функции не выполняют разматывание, как, скажем, исключения. Однако This MSDN page указывает, что реализация Microsoft может быть вызвана для вызова деструкторов локальных объектов, что подразумевает, что тщательное использование этих функций может быть безопасным.Есть ли безопасный способ использования setjmp() и longjmp() в C++?

Есть ли переносное средство обеспечения правильности программы при использовании setjmp() и longjmp() в C++? Лучшие практики на C++ указывают на то, что исключения лучше не использовать для управления потоком, но в ситуации, которая требует очень необычного потока (например, сопрограммы и замыкания), всегда предпочтительнее использовать исключения вместо этих функций?

+2

Для сопроводительных сообщений см. [* Как внедрить Coroutines в C++ *] (http://stackoverflow.com/questions/121757/how-do-you-implement-coroutines-in-c). – kennytm

+1

«в ситуации, которая требует очень необычного потока», действительно лучше спросить, как реализовать этот особый * необычный рабочий процесс *. Абстрактные вопросы редко приносят полезные ответы. – Dummy00001

+0

@ Dummy00001: Я вообще ссылался на различные применения 'setjmp()'/'longjmp()', предлагая примеры необычных конструктов управления, не пытаясь предположить, что я использую какой-то другой вид управления потоком данных магия. Я только спрашивал, есть ли безопасный способ использовать эти функции на C++, и я получил свой ответ. –

ответ

2

Если у вас есть какое-то действительно странное требование, которое не позволяет вам нормально управлять потоком программы, с условностями/циклами/перерывами, я бы предпочел использовать исключение для jmp.

Существуют сценарии, в которых использование исключения для потока управления приемлемо. Я думаю, что одна из функций поиска Boost.Graph выдает исключение, чтобы быстро вернуться к вызывающей стороне из глубокой рекурсии.

+0

Ну, тогда я предпочту исключения. Я все равно хотел бы знать, возможно ли * * уйти с '* jmp()'. –

+3

Нет, это невозможно сделать, сохраняя переносимость. Я просто тестировал в Windows с Visual Studio и Linux с gcc. Реализация VS правильно назвала деструкторы. Реализация gcc не уничтожила объекты, удаленные из стека. –

+0

У меня был случай, когда я создавал обертку вокруг старой библиотеки C (не помните, какой); эта библиотека требовала от меня передать функции обратного вызова и некоторые части этой библиотеки (которую я вызывал внутри обратных вызовов), где используется longjmp. Это тот код, который я надеюсь, мне никогда не придется отлаживать – Tomaka17

1

Я использовал их раньше, но только при одном: я создавал ядро ​​ОС в C для класса ОС; они использовались для обработки исключений.

Я понимаю, что они используются для обработки исключений при работе с низкоуровневым кодом, например операционной системой. Для общего программного обеспечения на C++ я бы просто использовал trycatch.

Смежные вопросы