Это хорошая практика программирования использовать setjmp и longjmp в C? - PullRequest
15 голосов
/ 31 августа 2011

Я программист на C ++ и привык к ОО-языкам с хорошей обработкой исключений.

Из того, что я могу понять, setjmp и longjmp по сути являются способом в стиле c для распространения условий исключений. Они также кажутся интенсивной формой гото, которая может распространяться вверх по стеку.

Итак, прежде всего: это хорошая практика - использовать их в прямом C на данный момент или они устарели? (примечание: C не C ++).

Во-вторых, имеют ли они какое-либо применение в C ++, или я прав, считая, что это устаревший механизм, который был заменен функциями обработки исключений в C ++?

Ответы [ 6 ]

7 голосов
/ 31 августа 2011

По сути, вы правы в своем утверждении, что распространение в стиле jmp по сути то же самое, что и goto.Прочитайте (известную и противоречивую) статью Дейкстры о goto s, которая (я думаю) дает разумное обоснование того, почему goto s следует использовать редко.Если вы не знаете точно, почему вы делаете то, что вы делаете (или вы работаете в очень специфических областях - например, во встроенном программировании), вам не следует касаться ни goto, ни longjmp.

5 голосов
/ 31 августа 2011

они используются для реализации сопрограмм.В сети работает несколько библиотек сопрограмм c ++, которые в Unix / Linux будут использовать setjmp/longjmp для реализации функциональности.

Итак, если ваша цель - реализовать библиотеку сопрограмм, тогдаспорный вопрос, если это хорошая практика или нет, поскольку на этих платформах это единственный способ для поддержки этой функциональности.

если ваша цель - использовать библиотеку сопрограмм, вы должны искатьнекоторые из них вместо этого.Существует даже предложение по улучшению хранилища, называемое boost :: context, которое уже одобрено.

4 голосов
/ 01 сентября 2011

Есть несколько правильных вариантов использования setjmp/longjmp. Реализация сопрограмм с ними практически невозможна, так как вы должны использовать (непереносимые) приемы (читай: встроенная сборка) для переключения стеков.

Одно из применений setjmp/longjmp - перехватывать сигналы с плавающей запятой, но это портит разматывание стека C ++. Исправьте в C, хотя.

Вы также можете реализовать некоторую форму разматывания стека (поддерживая свой собственный стек обработчика очистки) и реализовать с ними истинные деструкторы и исключения в C. Это очень удобно в больших проектах: отсутствие правильного механизма обработки ошибок является слабым местом в C. Однако это довольно сложно сделать правильно, и вам придется написать кучу макросы для облегчения задачи.

2 голосов
/ 31 августа 2011

Вы, конечно, не хотите использовать setjmp в C ++, поскольку вы говорите, что для этого есть исключения. Вы не хотите использовать их в C, потому что это очень трудно понять правильно. Очень старайся найти другие решения.

1 голос
/ 31 августа 2011

setjmp / longjmp - полезный способ реализовать собственную обработку исключений в чистом C. http://sourceware.org/pthreads-win32/announcement.html

0 голосов
/ 31 августа 2011

setjmp и longjmp - это макросы, используемые для обхода обычного вызова функции и обратного потока.
setjmp сохраняет вызывающий env для использования longjmp
Правильное использование этих макросов действительнотрудно, и вы можете легко получить неопределенное поведение.
Из-за этого, например, требуется ограничить longjmp до 1 уровня обработчика сигнала (лучше всего вообще не вызываться).
В критическомсистемы требуется не использовать вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...