私の質問は、ローカル変数に関する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修飾された型を持たず、setjmp()呼び出しとlongjmp()呼び出しの間で が変更される自動記憶期間は不定です。
私は2つの可能な解釈、以下を参照してください。
intepretation1:
ローカル変数が両方
- 非揮発性および
- が
侵入2:
個のローカル変数は
- 非揮発性であるものと
- longjmpをのみV1は未定義である後interpretation1によれば
を変更されているものを除いて、復元されます。 v2、v3、v4が定義される。 longjmpの後の解釈2によれば、v4のみが定義されています。 v1、v2、v3は未定義です。
どちらが正しいですか?
BTW:すべてのコンパイラに有効な一般的な( "ポータブルな")回答が必要です。つまり、特定のコンパイラを試してみても役に立ちません。
実装上の注意:変更された変数と不揮発性の変数は、longjmpの時と同じか、setjmpの時にコード生成によって復元されます。したがって、「不確定」。したがって、もしそれらが*変更されていなければ、これらの2つの値は同じであり、そのため変更されていないバールは安全です。 – greggo