Spec-Zone.ru › C

longjmp

Определён в заголовочном файле <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, выполнялась в другом потоке) также приводит к неопределённому поведению.

(начиная с C11)

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

При переходе вверх по стеку longjmp не освобождает память, занятую массивами переменной длины; если время их жизни завершается таким образом, возможны утечки памяти:

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
}
(начиная с C99)

Параметры

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

Примечания

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

Пример

#include <setjmp.h>
#include <stdio.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

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 7.13.2.1 Макрос longjmp (стр. 283–284)
  • Стандарт 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

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/program/longjmp

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API