Meine Fragen zielen auf das Verhalten von setjmp/longjmp in Bezug auf lokale Variablen ab.
Beispielcode:
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();
}
Die Dokumentation von setjmp/longjmp sagt:
„Alle zugänglichen Objekte haben Werte ab dem Zeitpunkt, an dem longjmp() aufgerufen wurde, außer dass die Werte von Objekten mit automatischer Speicherdauer, die lokal für die Funktion sind, die den Aufruf des entsprechenden setjmp() enthält, die keinen volatile-qualifizierten Typ haben und die zwischen dem Aufruf von setjmp() und dem Aufruf von longjmp() geändert werden, sind unbestimmt.”
Ich sehe folgende zwei mögliche Interpretationen:
Interpretation1:
Lokale Variablen werden wiederhergestellt, außer denen, die beides sind
- nicht flüchtig u
- geändert
Interpretation2:
Lokale Variablen werden wiederhergestellt, außer
- diejenigen, die nicht flüchtig sind und
- diejenigen, die geändert werden
Laut Interpretation1 ist nach longjmp nur v1 undefiniert. v2, v3, v4 sind definiert. Laut Interpretation2 ist nach longjmp nur v4 definiert. v1, v2, v3 sind undefiniert.
Welcher ist richtig?
Übrigens: Ich brauche eine allgemeine (“portable”) Antwort, die für alle Compiler gilt, dh das Ausprobieren mit einem bestimmten Compiler hilft nicht.
Hinweis zur Implementierung: Variablen, die geändert und nichtflüchtig sind, können je nach Codegenerierung so sein, wie sie zum Zeitpunkt von longjmp waren, oder auf den Stand zum Zeitpunkt von setjmp zurückgesetzt werden. Also „unbestimmt“. Also, wenn sie es wären nicht geändert, sind diese beiden Werte gleich und deshalb sind unveränderte Variablen sicher.
– Gregor
13. April 2012 um 21:27 Uhr