setjmp
| Определён в заголовочном файле <csetjmp>
|
||
| #define setjmp(env) /* зависит от реализации */ |
||
Сохраняет текущий контекст выполнения в переменную env, которая имеет тип std::jmp_buf. Этой переменной можно воспользоваться, чтобы позже восстановить текущий контекст выполнения с помощью функции std::longjmp. То есть, когда совершается вызов функции std::longjmp, выполнение продолжается с места, определённого в переменной std::jmp_buf, отправленной в функцию std::longjmp. В этом случае возвращенное значение функции setjmp передаётся функции std::longjmp.
Вызов setjmp должен совершён только в следующий местах:
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 находится в других местах, то поведение будет не определено.
По возвращении в блок с setjmp, все доступные объекты, статусные флаги числа с плавающей запятой и другие компоненты абстрактной машины будут иметь такие же значение, которые они имели, когда был вызван std::longjmp, исключая только не volatile локальные переменные в блоке с setjmp, чьё значение будет неопределенным, если они были изменены после вызова setjmp.
Содержание |
[править] Параметры
| env | — | Переменная для сохранения состояния выполнения программы |
[править] Возвращаемое значение
Если макрос был вызван из кода и контекст выполнения был сохранён в env, то возвращается 0. Другие значение возвращаются, если прыжок был не локальным, тогда возвращается тоже значение, что было передано std::longjmp.
[править] Пример
#include <iostream> #include <csetjmp> std::jmp_buf jump_buffer; [[noreturn]] void a(int count) { std::cout << "a(" << count << ") вызван\n"; std::longjmp(jump_buffer, count+1); // setjump() возвратит count+1 } int main() { volatile int count = 0; // Изменяемая локальная переменная в блоке setjmp должна быть volatile if (setjmp(jump_buffer) != 9) { // Оператор равенства с константным выражением в if a(count++); // Это приведёт к выходу из setjmp() } }
Вывод:
a(0) вызван a(1) вызван a(2) вызван a(3) вызван a(4) вызван a(5) вызван a(6) вызван a(7) вызван a(8) вызван
[править] См. также
| Переход на указанное место (функция) | |
| Справка по C — setjmp
| |

