====== setjmp.h ====== заголовочник объявляющий макросы и тип данных для нелокальных переходов. В Си существует оператор goto, позволяющий переходить в любое место в пределах функции (с некоторыми оговорками), однако переход между функциями с его помощью невозможен. определения: #include 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, и заставляет ранее вызванный setjmp((Если функция была вызвана без соответствующего вызова setjmp(), или функция, в которой восстанавливается выполнение, уже завершилась, то поведение не определено.)) вернуться с значением val (если val == 0, оно преобразуется в 1). Выполнение продолжается как будто setjmp только что вернуло это значение. наглядное объяснение: {{:c:c_ultimate_guide:2025-10-31_13-23.png}} Использование setjmp() и longjmp() может привести к утечкам памяти, если выделение происходит между вызовами этих функций. О памяти: * глобальные сохраняються * динамическая память остаеться как была * файлы и т.п. остаються как были * локальные непредсказуемы (если только их жестко не привязать к памяти через ''volatile''(никаких регистров и прочих оптимизаций)) пример: #include #include 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; }