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(){volatileint count =0;// изменяемые локальные переменные в области видимости// setjmp должны быть volatileif(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 |