setjmp
| Определено в заголовочном файле <csetjmp>
|
||
| #define setjmp(env) /* зависит от реализации */ |
||
Сохраняет текущий контекст выполнения в переменную env типа std::jmp_buf. Позже эту переменную можно использовать для восстановления текущего контекста выполнения с помощью функции std::longjmp. То есть, когда совершается вызов функции std::longjmp, выполнение продолжается с конкретного места вызова, который создал переменную std::jmp_buf, переданную std::longjmp. В этом случае возвращаемое значение setjmp передаётся функции std::longjmp.
Вызов setjmp должен появляться только в одном из следующих контекстов:
- все управляющие выражения if, switch, while, do-while, for.
switch(setjmp(env)) { //..
- один операнд в операторах сравнения или равенства, когда другой операнд является константным целочисленным значением, когда результат этого выражения находится в операторах управления: if, switch, while, do-while, for.
if(setjmp(env) > 0) { //...
- операнд унарного оператора !, когда результат этого выражения находится в операторах управления: if, switch, while, do-while, for.
while(!setjmp(env)) { //...
- всё выражение оператора (возможно, приведённое к
void).setjmp(env);
Если setjmp находится в любом другом контексте, поведение не определено.
|
Кроме того, поведение не определено, если |
(начиная с C++20) |
По возвращении в блок с setjmp:
- все доступные объекты, статусные флаги числа с плавающей запятой и другие компоненты абстрактной машины будут иметь такие же значения, которые они имели, когда был вызван std::longjmp
- исключая только не volatile локальные переменные в функции, содержащей вызов
setjmp, чьё значение будет неопределённым, если они были изменены после вызова setjmp.
Содержание |
[править] Параметры
| env | — | переменная для сохранения состояния выполнения программы |
[править] Возвращаемое значение
0, если макрос был вызван из кода и контекст выполнения был сохранён в env.
Ненулевое значение, если только что был выполнен нелокальный переход. Возвращаемое значение совпадает с переданным в std::longjmp.
[править] Примечание
Приведённые выше требования запрещают использование возвращаемого значения setjmp в потоке данных (например, для инициализации или присваивания объекта с его помощью). Возвращаемое значение может быть либо использовано в потоке управления, либо отброшено.
[править] Пример
#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 по setjmp
| |

