Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

Стандарт С утверждает, что даже если

longjmp
вызывается со вторым аргументом, равным 0,
setjmp
по-прежнему возвращает ненулевое значение. В таком случае она возвращает 1.

Возможность передать целое значение и вернуться обратно из

setjmp
полезна; это позволяет коду уровня пользователя различать причину перехода. Например,
gawk
использует эту возможность для обработки операторов
break
и
continue
внутри циклов. (Язык awk осознанно сделан похожим на С в своем синтаксисе для циклов, с использованием
while
,
do-while
,
for
,
break
и
continue
.) Использование
setjmp
выглядит следующим образом (из
eval.c
в дистрибутиве
gawk
3.1.3):

507 case Node_K_while:

508 PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);

509

510 stable_tree = tree;

511 while (eval_condition(stable_tree->lnode)) {

512 INCREMENT(stable_tree->exec_count);

513 switch (setjmp(loop_tag)) {

514 case 0: /* обычный не переход */

515 (void)interpret(stable_tree->rnode);

516 break;

517 case TAG_CONTINUE: /* оператор continue */

518 break;

519 case TAG_BREAK: /* оператор break */

520 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);

521 return 1;

522 default:

523 cant_happen;

524 }

525 }

526 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);

527 break;

Этот фрагмент кода представляет цикл

while
. Строка 508 управляет вложенными циклами посредством стека сохраненных переменных
jmp_buf
. Строки 511–524 выполняют цикл
while
(используя цикл С
while
!). Строка 511 проверяет условие цикла. Если оно истинно, строка 513 выполняет
switch
на возвращаемое значение
setjmp
. Если оно равно 0 (строки 514–516), строка 515 выполняет тело оператора. Однако, когда
setjmp
возвращает
TAG_BREAK
или
TAG_CONTINUE
, оператор
switch
обрабатывает их соответствующим образом (строки 517–518 и 519–521 соответственно).

Оператор

break
на уровне
awk
передает
TAG_BREAK
функции
longjmp
, a
continue
уровня
awk
передает
TAG_CONTINUE
. Снова из
eval.c
с некоторыми пропущенными не относящимися к делу подробностями:

657 case Node_K_break:

658 INCREMENT(tree->exec_count);

/* ... */

675 longjmp(loop_tag, TAG_BREAK);

676 break;

677

678 case Node_K_continue:

679 INCREMENT(tree->exec_count);

/* ... */

696 longjmp(loop_tag, TAG_CONTINUE);

670 break;

Вы можете думать о

setjmp
как об установке метки, а о
longjmp
как выполнении
goto
с дополнительным преимуществом возможности сказать, откуда «пришел» код (по возвращаемому значению).

12.5.2. Обработка масок сигналов:

sigsetjmp
и
siglongjmp

По историческим причинам, которые, скорее всего, утомили бы вас до слез, стандарт С 1999 г. ничего не говорит о влиянии

setjmp
и
longjmp
на состояние сигналов процесса, а POSIX явно констатирует, что их влияние на маску сигналов процесса (см. раздел 10.6 «Сигналы POSIX») не определено.

Другими словами, если программа изменяет свою маску сигналов процесса между первым вызовом

setjmp
и вызовом
longjmp
, каково состояние маски сигналов процесса после
longjmp
? Та ли эта маска, когда была впервые вызвана
setjmp
? Или это текущая маска? POSIX явно утверждает, что «нет способа это узнать».

Чтобы сделать обработку маски сигналов процесса явной, POSIX ввел две дополнительные функции и один

typedef
:

#include <setjmp.h> /* POSIX */

int sigsetjmp(sigjmp_buf env, int savesigs); /* Обратите внимание:

sigjmp_buf, не jmp_buf! */

void siglongjmp(sigjmp_buf env, int val);

Главным отличием является аргумент

savesigs
функции
sigsetjmp
. Если он не равен нулю, текущий набор заблокированных сигналов сохраняется в
env
вместе с остальным окружением, которое сохраняется функцией
setjmp
.
siglongjmp
с
env
, в которой
savesigs
содержала true, восстанавливает сохраненную маску сигналов процесса

ЗАМЕЧАНИЕ. POSIX также ясен в том, что если

savesigs
равен нулю (false), сохраняется ли маска сигналов процесса или восстанавливается, не определено, как в случае с
setjmp
/
longjmp
. Это, в свою очередь, предполагает, что если собираетесь использовать '
sigsetjmp(env, 0)
', вы также можете не беспокоиться: все дело в том, чтобы иметь контроль над сохранением и восстановлением маски сигналов процесса!

12.5.3. Важные предостережения

Есть несколько технических предостережений, о которых нужно знать.

Во-первых, поскольку сохранение и восстановление среды может быть беспорядочной машинно-зависимой задачей,

setjmp
и
longjmp
могут быть макросами

Во-вторых, стандарт С ограничивает использование

setjmp
следующими ситуациями.

• В качестве единственного контролирующего выражения в операторе цикла или условном операторе (

if
,
switch
).

Поделиться:
Популярные книги

Виктор Глухов агент Ада. Компиляция. Книги 1-15

Сухинин Владимир Александрович
Виктор Глухов агент Ада
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Виктор Глухов агент Ада. Компиляция. Книги 1-15

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Геном хищника. Книга шестая

Гарцевич Евгений Александрович
6. Я - Легенда!
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Геном хищника. Книга шестая

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

Память льда

Эриксон Стивен
3. «Малазанская империя»
Фантастика:
фэнтези
6.00
рейтинг книги
Память льда

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

На границе империй. Том 10. Часть 7

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 7

Пышка (сборник)

Де Мопассан Ги
Проза:
классическая проза
8.45
рейтинг книги
Пышка (сборник)

Черный Маг Императора 16

Герда Александр
16. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 16

И.Бабель. Воспоминания современников

Паустовский Константин Георгиевич
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
И.Бабель. Воспоминания современников

Убивать чтобы жить 4

Бор Жорж
4. УЧЖ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 4

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

По осколкам твоего сердца

Джейн Анна
2. Хулиган и новенькая
Любовные романы:
современные любовные романы
5.56
рейтинг книги
По осколкам твоего сердца

Источник

Билик Дмитрий Александрович
11. Бедовый
Фантастика:
юмористическое фэнтези
городское фэнтези
мистика
7.00
рейтинг книги
Источник