Namespaces
Variants

longjmp

From cppreference.net
Определено в заголовочном файле <setjmp.h>
void longjmp ( jmp_buf env, int status ) ;
(до C11)
_Noreturn void longjmp ( jmp_buf env, int status ) ;
(начиная с C11)
(до C23)
[ [ noreturn ] ] void longjmp ( jmp_buf env, int status ) ;
(начиная с C23)

Загружает контекст выполнения env , сохранённый предыдущим вызовом setjmp . Эта функция не возвращает управление. Управление передаётся в точку вызова макроса setjmp , который установил env . Затем этот setjmp возвращает значение, переданное в качестве status .

Если функция, которая вызвала setjmp завершилась (либо через возврат, либо с помощью другого longjmp выше по стеку), поведение не определено. Другими словами, разрешены только длинные переходы вверх по стеку вызовов.

Переход между потоками (если функция, вызвавшая setjmp , была выполнена другим потоком) также является неопределённым поведением.

(since C11)

Если при вызове setjmp в области видимости находилась переменная VLA или другого изменяемого типа и управление покинуло эту область, longjmp к этому setjmp вызывает неопределённое поведение, даже если управление осталось в пределах функции.

При подъёме по стеку longjmp не освобождает память VLA, что может привести к утечкам памяти, если их время жизни завершается таким образом:

void g(int n)
{
    int a[n]; // a may remain allocated
    h(n); // does not return
}
void h(int n)
{
    int b[n]; // b may remain allocated
    longjmp(buf, 2); // might cause a memory leak for h's b and g's a
}
(since C99)

Содержание

Параметры

env - переменная, ссылающаяся на состояние выполнения программы, сохраненное setjmp
status - значение, возвращаемое из setjmp . Если оно равно 0 , используется 1 вместо него

Возвращаемое значение

(нет)

Примечания

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

Пример

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
jmp_buf my_jump_buffer;
noreturn void foo(int status) 
{
    printf("foo(%d) called\n", status);
    longjmp(my_jump_buffer, status + 1); // will return status+1 out of setjmp
}
int main(void)
{
    volatile int count = 0; // modified local vars in setjmp scope must be volatile
    if (setjmp(my_jump_buffer) != 5) // compare against constant in an if
        foo(++count);
}

Вывод:

foo(1) called
foo(2) called
foo(3) called
foo(4) called

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.13.2.1 Макрос longjmp (стр: 191-192)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.13.2.1 Макрос longjmp (стр: 263-264)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.13.2.1 Макрос longjmp (стр: 244-245)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.6.2.1 Функция longjmp

Смотрите также

сохраняет контекст
(функция-макрос)
C++ documentation для longjmp