мета-данные страницы
setjmp.h
заголовочник объявляющий макросы и тип данных для нелокальных переходов. В Си существует оператор goto, позволяющий переходить в любое место в пределах функции (с некоторыми оговорками), однако переход между функциями с его помощью невозможен.
определения:
#include <setjmp.h> int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val);
описание:
jmp_buf— тип данных, представляющий сохранённое состояние выполнения (контекст), включая регистры, указатель стека и указатель инструкции. Размер и содержимое зависят от реализации.setjmp(env)— (по простому - сохраняет точку возврата) сохраняет текущий контекст в env и возвращает 0 при прямом вызове. При последующем возвращении, инициированном longjmp, setjmp возвращает ненулевое значение, переданное в longjmp.longjmp(env, val)— (по простому - возвращаеться в точку возврата) восстанавливает контекст, ранее сохранённый в env, и заставляет ранее вызванный setjmp1) вернуться с значением val (если val == 0, оно преобразуется в 1). Выполнение продолжается как будто setjmp только что вернуло это значение.
Использование setjmp() и longjmp() может привести к утечкам памяти, если выделение происходит между вызовами этих функций.
О памяти:
- глобальные сохраняються
- динамическая память остаеться как была
- файлы и т.п. остаються как были
- локальные непредсказуемы (если только их жестко не привязать к памяти через
volatile(никаких регистров и прочих оптимизаций))
пример:
#include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) { printf("вторая функция: собираюсь longjmp\n"); longjmp(buf, 42); } void first(void) { second(); printf("это не будет выполнено\n"); } int main(void) { int val = setjmp(buf); if (val == 0) { printf("setjmp вернул 0 — нормальный путь\n"); first(); } else { printf("setjmp вернул %d — вернулись из longjmp\n", val); } return 0; }
