setjmp/longjmp y variables locales
(2)
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".
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 un tipo calificado como 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
Según 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?
Por cierto: necesito una respuesta general ("portátil") que sea válida para todos los compiladores, es decir, probar con un compilador en particular no ayuda.
setjmp / longjmp se implementa guardando los registros (incluidos los punteros de apilamiento 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 pila) que no son "volátiles" pueden almacenarse en registros en lugar de en la pila.
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 compilador especialmente 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 compilador 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 compilador, y por lo tanto no es nada en lo que deba confiar (''indeterminado'').