Стандартная библиотека C -<setjmp.h>
Введение
setjmp.hЗаголовочный файл определяет макросыsetjmp(), функциюlongjmp()и типы переменныхjmp_buf, этот тип переменной обходит обычные правила вызова и возврата из функций.
<setjmp.h>является заголовочным файлом в стандартной библиотеке C, который предоставляет набор функций и макросов для нелокальных переходов (то есть переходов из одной функции в другую функцию, которая была вызвана ранее, без необходимости обычного возврата из функции). Этот механизм обычно используется для обработки ошибок, обработки исключений или выхода из глубоко вложенных циклов или рекурсии.
Переменные библиотеки
Ниже перечислены переменные, определённые в заголовочном файле setjmp.h:
| Порядковый номер | Переменные и описание |
|---|---|
| 1 | jmp_buf
|
Библиотечные макросы
Ниже приведён единственный макрос, определённый в этой библиотеке:
| Порядковый номер | Макросы и описание |
|---|---|
| 1 | int setjmp(jmp_buf environment) Этот макрос сохраняет текущее окружение в переменнойenvironmentчтобы функцияlongjmp()могла использовать его позже. Если этот макрос возвращает управление непосредственно из вызова макроса, он возвращает ноль, но если он возвращает управление из вызоваlongjmp()вызова функции, он возвращает ненулевое значение. |
Библиотечные функции
Ниже описана единственная функция, определённая в заголовочном файле setjmp.h:
| Порядковый номер | Функции и описание |
|---|---|
| 1 | void longjmp(jmp_buf environment, int value) Эта функция восстанавливает окружение, сохранённое при последнем вызовеsetjmp()когда был вызван макрос,jmp_bufЗначение параметра задаётся предыдущим вызовом setjmp(). |
Пример
В следующем примере показано, как использовать setjmp() и longjmp() для реализации нелокальных переходов:
Пример
#include <setjmp.h>
jmp_buf env;
void second() {
printf("Вход в second()\n");
longjmp(env, 1);
printf("Эта строка никогда не будет выполнена\n");
}
void first() {
printf("Вход в first()\n");
if (setjmp(env) == 0) {
printf("Вызов second() из first()\n");
second();
} else {
printf("Возврат в first() из second() с помощью longjmp\n");
}
printf("Выход из first()\n");
}
int main() {
printf("Запуск main()\n");
first();
printf("Выход из main()\n");
return 0;
}
Выполнение вышеуказанной программы выведет примерно следующее:
Starting main() Entering first() Calling second() from first() Entering second() Returned to first() from second() using longjmp Exiting first() Exiting main()
Пояснение кода
jmp_buf env: определить переменную для сохранения информации об окруженииenv。first()функция: вызовsetjmp(env)сохранить информацию о текущем окружении и решить, вызывать ли его на основе возвращаемого значенияsecond()функцию.second()функция: вызовlongjmp(env, 1), вернуться обратно кsetjmp(env), и заставить её вернуть 1.main()функция: вызовfirst()функцию.
Сценарий использования
- Обработка ошибок: используется при глубоко вложенных вызовах функций
setjmp()иlongjmp()чтобы реализовать механизм обработки ошибок. - Обработка исключений: используется для реализации простой обработки исключений.
- прервать поток управления: в некоторых случаях нормальный поток управления можно прервать, чтобы выйти из нескольких уровней вложенных циклов или вызовов функций.
Примечания
- Использование
setjmp()иlongjmp()Нужно быть осторожным, потому что они пропускают обычный процесс раскрутки стека, что может привести к утечкам ресурсов (таким как неосвобождённая память, незакрытые файлы и т. д.). - избегать при вызове
setjmp()иlongjmp()между изменением локальных переменных, потому что это может привести к неопределённому поведению. - Нелокальные переходы могут затруднить чтение и отладку кода, поэтому их следует использовать с осторожностью.
Итог
<setjmp.h>предоставляетsetjmp()иlongjmp()функции, используемые для реализации нелокальных переходов. Эти функции очень полезны при обработке ошибок и обработке исключений, но их нужно использовать с осторожностью, чтобы избежать потенциальных проблем.