Подтвердить что ты не робот

Является ли хорошей практикой программирования использовать setjmp и longjmp в C?

Я программист на С++ и использую языки OO с хорошей обработкой исключений.

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 6

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