setjmp / longjmp y variables locales

Mis preguntas apuntan al comportamiento de setjmp / longjmp con respecto a las variables locales.

Código de ejemplo:

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(); } 

La documentación de setjmp / longjmp dice:

“Todos los objetos accesibles tienen valores desde el momento en que se llamó a longjmp (), excepto que los valores de los objetos de duración de almacenamiento automático que son locales a la función que contiene la invocación del conjunto setjmp () que no tienen el tipo calificado volátil y que se cambian entre la invocación setjmp () y la llamada longjmp () son indeterminadas. ”

Veo siguientes dos posibles interpretaciones:

interpretación1:

Las variables locales son restauradas, excepto aquellas que son ambas

  • no volátil y
  • cambiado

interpretación2:

Las variables locales se restauran, excepto

  • aquellos que son no volátiles y
  • los que se cambian

De acuerdo con la interpretación 1 después de longjmp solo v1 está indefinido. v2, v3, v4 están definidos. De acuerdo con la interpretación 2 después de longjmp solo se define v4. v1, v2, v3 están indefinidos.

¿Cuál es la correcta?

BTW: Necesito una respuesta general (“portátil”) que sea válida para todos los comstackdores, es decir, probar con un comstackdor en particular no ayuda.

La interpretación 1 es correcta. Si se pretendía la Interpretación 2, el texto original habría usado ” o que se han cambiado” en lugar de “y”.

setjmp / longjmp se implementa guardando los registros (incluidos los punteros de astackmiento y código, etc.) cuando se pasan por primera vez, y restaurándolos al saltar.

Las variables automáticas (también conocidas como “locales”, asignadas a la stack) que no son “volátiles” pueden almacenarse en registros en lugar de en la stack.

En estas circunstancias, longjmp restaurará estas variables de registros a su valor en el punto en que se llamó por primera vez a setjmp ().

Además, un comstackdor particularmente inteligente podría evitar las variables que pueden inferirse del estado de otra variable y calcularlas según la demanda.

Sin embargo, si la variable es automática pero no se le ha asignado un registro, puede cambiarse mediante un código entre setjmp y longjmp.

Volatile le dice explícitamente al comstackdor que no almacene la variable en un registro.

Entonces, a menos que diga explícitamente que una variable es volátil, si cambió la variable entre setjmp / longjmp, su valor dependerá de las elecciones que haga el comstackdor y, por lo tanto, no es nada en lo que deba confiar (‘indeterminado’).