std::longjmp
| Определено в заголовочном файле <csetjmp>
|
||
void longjmp( std::jmp_buf env, int status ); |
||
Загружает контекст выполнения env, сохранённый при предыдущем вызове setjmp. Эта функция никогда не возвращает управление. Управление передаётся в место вызова макроса setjmp, которое установило значение env. Также setjmp затем возвращает значение, которое было передано как status.
Если функция, которая вызвала setjmp завершилась, поведение не определено (другими словами разрешены только длинные переходы вверх по стеку вызова).
Дополнительные ограничения в C++
Помимо C longjmp, C++ std::longjmp имеет более ограниченное поведение.
Если заменить std::longjmp на throw и setjmp на catch вызовет нетривиальный деструктор для любого автоматического объект, поведение такого std::longjmp не определено.
|
Поведение не определено, если |
(начиная с C++20) |
Параметры
| env | — | переменная, которая хранит состояние выполнение программы, сохранённое с помощью вызова std::setjmp |
| status | — | значение, возвращаемое setjmp. Если оно равно 0, вместо него используется 1
|
Возвращаемое значение
(нет)
Примечание
std::longjmp это механизм, использовавшийся в C для перехвата неожиданных ошибочных ситуаций, когда функция не могла вернуть никакое значение. C++ для этой цели обычно использует обработку исключений.
Пример
#include <csetjmp>
#include <iostream>
std::jmp_buf my_jump_buffer;
[[noreturn]] void foo(int status)
{
std::cout << "foo(" << status << ") вызвана\n";
std::longjmp(my_jump_buffer, status+1); // setjmp() вернёт status+1
}
int main()
{
volatile int count = 0; // изменяемые локальные переменные в области видимости
// setjmp должны быть volatile
if (setjmp(my_jump_buffer) != 5)
{ // равенство против константного выражения в if
count += 1; // Инкремент volatile переменной устарел, начиная с C++20 (P1152)
foo(count); // Это приведёт setjmp() к выходу
}
}
Вывод:
foo(1) вызвана
foo(2) вызвана
foo(3) вызвана
foo(4) вызвана
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 619 | C++98 | формулировка дополнительных ограничений в C++ была расплывчатой |
формулировка улучшена |
| LWG 894 | C++98 | поведение было неопределенным, если замена std::longjmpна throw и setjmp на catch уничтожила бы любойавтоматический объект |
поведение не определено только в том случае, если вызывается нетривиальный деструктор для любого автоматического объекта |
Смотрите также
| сохраняет контекст (функция-макрос) | |
Документация C по longjmp
| |