Что такое автоматическая переменная в этом контексте setjmp / longjmp? - PullRequest
9 голосов
/ 01 сентября 2011

Расширенное программирование в среде UNIX У. Ричард Стивенс утверждает:

"Каковы состояния автоматических переменных и регистров переменные в основной функции? "

в отношении того, что происходит, когда вы longjmp возвращаетесь к основному (или к другой функции) где-то ниже в стеке.

Далее говорится:

"Это зависит. Большинство реализаций не пытаются откатить эти автоматические переменные и переменные регистров, но все это стандарты говорят, что их значения являются неопределенными. Если у вас есть автоматический переменная, которую вы не хотите откатывать, определите ее с помощью volatile атрибут. Переменные, которые объявлены глобальными или статическими остаются одни, когда longjmp выполняется.

Похоже, он говорит, что нормальным переменным стека не будут возвращаться значения, равные значениям, установленным во время setjmp - но тогда остальная часть функции не могла полагаться на свои переменные стека после возврата longjmp назад. к этому, который кажется сумасшедшим, так что я предполагаю, что я неправ.

Может ли кто-нибудь определить для меня «автоматические переменные» и объяснить, что конкретно не возвращается к его первоначальному значению и почему это так?

Ответы [ 5 ]

6 голосов
/ 01 сентября 2011

«Автоматические переменные» - это старый термин для обычных (не объявляемых с помощью регистра или статических) локальных переменных, который восходит к терминологии, используемой в стандарте C, и первоначальному значению ключевого слова auto.См. Разделы 6.2.4 и 6.7.1 стандарта

Что касается этого:

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

Идея состоит в том, что вы не должны изменять их в первую очередь, если вы собираетесь использовать longjmp, потому что тогда вы не можете знать,Что должно случиться.

Причина заключается в том, что longjmp может восстанавливать состояние, такое как регистры процессора, которым автоматические переменные могли быть сопоставлены (нет гарантии, что они будут в «стеке» или в памятии даже если они существуют в памяти, некоторые операции могут (если только они не объявлены как энергозависимые) не имеют прямого доступа к памяти, но могут получить доступ к регистру процессора, в который уже загружено значение)

Ваш вопросэто немного странно, потому что это означает, что вы хотите их восстановить [т.е. ваши изменения во промежуточных функциях должны быть удалены] - в общем, это предостережение о том, что они могут быть восстановлены аварией когда это не ожидается.«Не восстановлено» не означает «непригодный для использования» [хотя стандарт DOES объявляет их непригодными для использования, поскольку он может восстановить кэшированный регистр, но не память, поэтому вы получите противоречивые результаты], это означает «имеет значение, записанное в более поздней функции»это (потому что вы передали адрес, предназначенный для его записи) ".

6 голосов
/ 01 сентября 2011

Все, что он говорит, это то, что если

  1. , то у вас есть автоматическая (локальная не-статическая) переменная, которая не объявлена ​​volatile
  2. вы меняете значение переменной между setjmp и longjmp

, затем после longjmp значение этой переменной становится неопределенным.

Я полагаю, что это связано с возможностью того, что такие переменные находятся в регистрах ЦП, а не в ОЗУ, и связанной с этим трудностью сохранения значений такой переменной в longjmp.

Вот цитата изgcc руководство :

Если вы используете longjmp, остерегайтесь автоматических переменных.ISO C говорит, что автоматические переменные, которые не объявлены volatile, имеют неопределенные значения после longjmp.И это все, что GCC обещает сделать, потому что очень трудно правильно восстановить переменные регистра, и одна из особенностей GCC состоит в том, что он может помещать переменные в регистры без вашего запроса.

Еслипотенциальная потеря значений переменных является проблемой в вашем случае использования, объявите соответствующие переменные как volatile.

0 голосов
/ 01 сентября 2011

Я не могу определить «автоматическую переменную», но, возможно, это поможет вам понять, что происходит во время setjump:

(некоторых из) процессоров, которые регистрируются и сохраняются вфайл.

и во время longjump:

значение регистров ЦП сбрасывается на сохраненное значение.

больше ничего!( здесь является примером)

Итак, во время longjump вы просто возвращаетесь в стек выше, все ваши переменные сохраняются в памяти нетронутыми ,и некоторые (не все) из регистров, в частности stack pointer и instruction pointer сбрасываются до значения, которое они имели во время setjmp.

0 голосов
/ 01 сентября 2011

auto означает все, что является локальным для функции и специально не определено как static.Вероятно, стоит отметить, что стандарт в значительной степени определяет его поведение (§7.13.2 / 3):

Все доступные объекты имеют значения, а все остальные компоненты абстрактной машины имеют состояние, каквремени была вызвана функция longjmp, за исключением того, что значения объектов длительности автоматического хранения, которые являются локальными для функции, содержащей вызов соответствующего макроса setjmp, не имеют тип volatile-qualified и были изменены между вызовом setjmp иВызов longjmp неопределен.

0 голосов
/ 01 сентября 2011

Автоматические переменные являются обычными локальными переменными функций - поскольку они расположены в стеке, и вам не нужно заботиться об их памяти, они называются automatic .

См. http://en.wikipedia.org/wiki/Automatic_variable для более подробного описания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...