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) или другая переменная с изменяемой длиной (variably-modified type) находилась в области видимости и управление покинуло эту область, 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
}
(с 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

См. также

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

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

Spec-Zone.ru

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