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
|