c - setjmp/longjmp и локальные переменные



(2)

setjmp / longjmp реализуется путем сохранения регистров (включая указатели стека и кода и т. д.) при первой передаче и восстановления их при переходе.

Автоматические (то есть «локальные», размещенные в стеке) переменные, которые не являются «volatile», могут храниться в регистрах, а не в стеке.

В этих условиях longjmp восстановит переменные этих регистров до их значения в тот момент, когда setjmp () был впервые вызван.

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

Однако, если переменная автоматическая, но ей не присвоен регистр, она может быть изменена кодом между setjmp и longjmp.

Volatile явно указывает компилятору не хранить переменную в регистре.

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

Мои вопросы направлены на поведение setjmp / longjmp относительно локальных переменных.

Пример кода:

jmp_buf env;


void abc()
{
  int error;

  ... 
  if(error)
    longjmp(env);
}


void xyz() {
  int v1;           // non-volatile; changed between setjmp and longjmp
  int v2;           // non-volatile; not changed between setjmp and longjmp
  volatile int v3;  // volatile;     changed between setjmp and longjmp
  volatile int v4;  // volatile;     not changed between setjmp and longjmp 

  ...

  if(setjmp(env)) {
    // error handling
    ...
    return;
  }

  v1++; // change v1
  v3++; // change v3

  abc();
}


int main(...) {
  xyz();
}

Документация setjmp / longjmp гласит:

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

Я вижу следующие две возможные интерпретации:

intepretation1:

Локальные переменные восстанавливаются, кроме тех, которые оба

  • энергонезависимый и
  • изменено

intepretation2:

Локальные переменные восстанавливаются, кроме

  • те, которые являются энергонезависимыми и
  • те, которые изменены

Согласно интерпретации 1 после longjmp, только v1 не определено. v2, v3, v4 определены. Согласно интерпретации2 после longjmp определяется только v4. v1, v2, v3 не определены.

Какой из них прав?

Кстати: мне нужен общий («переносимый») ответ, который действителен для всех компиляторов, т.е. попытка с одним конкретным компилятором не поможет.


Интерпретация 1 верна. Если бы толкование 2 было задумано, в исходном тексте использовалось бы « или которые были изменены» вместо «и».





c