мета-данные страницы
  •  

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;
}
1)
Если функция была вызвана без соответствующего вызова setjmp(), или функция, в которой восстанавливается выполнение, уже завершилась, то поведение не определено.