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
interpretación2:
Las variables locales se restauran, excepto
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’).