Можно и допустимо ли сделать копию jmp_buf и восстановить ее позже? что-то вроде
jmp_buf oldEnv = env;
int val = setjmp(env);
.......
env = oldEnv;
Я использовал memcopy () и sizeof (env), чтобы скопировать данные jmp_buf. Кажется, это работает нормально. это просто совпадение?
В соответствии с http://en.cppreference.com/w/c/program/jmp_buf тип jmp_buf не указан. Таким образом, вы не знаете, что вы собираетесь получить, когда вы на самом деле используете jmp_buf
и sizeof может не возвращать фактический размер памяти, которую вы хотите скопировать. Возможно, подойдут memcpy и sizeof, но поскольку вы не знаете наверняка, вы можете столкнуться со всеми видами ошибок.
Это также вызывает вопрос, почему вы хотите скопировать его? Содержимое jmp_buf не должно использоваться вами вообще. Все, что вы делаете, — это предоставление места для хранения ОС, когда setjmp заполняет env
, Как сказал Рон Попейл: «Поставь и забудь».
Вы можете сделать это, только если вы ничего не делаете с jmp_buf
в промежутке В частности, вы не можете позвонить setjmp
опять восстановить старое jmp_buf
содержание и использование longjmp
чтобы вернуться к более раннему setjmp
вызов.
Правило в стандарте C:
longjmp
функция восстанавливает среду, сохраненную самый последний вызовsetjmp
макрос в том же вызове программы с соответствующимjmp_buf
аргумент.
Так как jmp_buf
это «тип массива», вызов longjmp
фактически передает разрушенный указатель; это фактический адрес jmp_buf
что приведенное выше словосочетание в отношении «соответствующего jmp_buf
аргумент «ссылки, а не только его содержание.
Я не знаю, как Стандарт гарантирует, что вы вернетесь к контексту самых последних setbuf
, если вы копались с содержимым jmp_buf
поэтому я бы отнесся к любой модификации jmp_buf
как сделать его полностью непригодным для longjmp
цели.
Если вы знаете что-то о внутренней компоновке вашей конкретной платформы, и вы используете jmp_buf
чтобы сохранить контекст процессора, чтобы войти в журнал отладки, такие вещи хороши. Но копии не могут быть использованы с longjmp
,
Единственный способ сделать это безопасно — реализовать свой собственный setjmp / longjmp Двойник. К счастью, это легко сделать для большинства пар компилятор / архитектура.