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

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

Жанры

Linux программирование в примерах
Шрифт:

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
).

• В качестве одного операнда выражения сравнения (

==
,
<
и т.д.), с целой константой в качестве другого операнда. Выражение сравнения может быть единственный контролирующим выражением цикла или условного оператора.

• В качестве операнда унарного оператора '

!
', причем результирующее выражение является единственным контролирующим выражением цикла или условного оператора.

• В качестве всего выражения оператора-выражения, возможно, приведенного к типу

void
. Например:

(void)setjmp(buf);

В-третьих, если вы хотите изменить локальную переменную в функции, которая вызывает

setjmp
, после вызова и хотите, чтобы эта переменная сохранила свое последнее присвоенное после
longjmp
значение, нужно объявить эту переменную как
volatile
. В противном случае все локальные переменные, не являющиеся
volatile
и изменившиеся после того, как была первоначально вызвана
setjmp
, имеют неопределенные значения. (Обратите внимание, что сама переменная
jmp_buf
не должна объявляться как
volatile
.) Например:

1 /* ch12-setjmp.с --- демонстрирует setjmp/longjmp и volatile. */

2

3 #include <stdio.h>

4 #include <setjmp.h>

5

6 jmp_buf env;

7

8 /* comeback --- выполнение longjmp */

9

10 void comeback(void)

11 {

12 longjmp(env, 1);

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

Шайтан Иван 3

Тен Эдуард
3. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Шайтан Иван 3

Матабар

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

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Бестужев. Служба Государевой Безопасности

Измайлов Сергей
1. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности

Солнечный флот

Вайс Александр
4. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Солнечный флот

За Горизонтом

Вайс Александр
8. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
За Горизонтом

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

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

Тринадцатый X

NikL
10. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Тринадцатый X

Последний Герой. Том 4

Дамиров Рафаэль
Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 4

Удержать 13-го

Уолш Хлоя
Любовные романы:
остросюжетные любовные романы
эро литература
зарубежные любовные романы
5.00
рейтинг книги
Удержать 13-го

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род

Убийца

Бубела Олег Николаевич
3. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Убийца

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

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