「揮発性」修飾子がない場合の問題の最も一般的な理由は、コンパイラがローカル変数をレジスタに配置することが多いためです。これらのレジスタは、ほぼ確実に setjmp と longjmp の間の他の目的で使用されます。これらのレジスターを他の目的で使用することによって、longjmp の後で変数が誤った値を保持しないようにする最も実用的な方法は、これらのレジスターの値を jmp_buf にキャッシュすることです。これは機能しますが、コンパイラーが jmp_buf の内容を更新して、レジスターがキャッシュされた後に変数に加えられた変更を反映する方法がないという副作用があります。
それが唯一の問題である場合、volatile と宣言されていないローカル変数にアクセスした結果は不確定になりますが、未定義の動作にはなりません。ただし、メモリ変数にも問題があります。これは、thiton が暗示しています。たとえローカル変数がたまたまスタックに割り当てられていたとしても、コンパイラは、その値がもはや存在しないと判断したときはいつでも、その変数を別のもので自由に上書きできます。必要です。たとえば、コンパイラは、ルーチンが他のルーチンを呼び出したときに一部の変数が「ライブ」にならないことを識別し、それらの変数をスタック フレームの最も浅い位置に配置して、他のルーチンを呼び出す前にポップすることができます。このようなシナリオでは、setjmp() が呼び出されたときに変数がメモリ内に存在していたとしても、そのメモリはリターン アドレスを保持するなどの別の用途に再利用されている可能性があります。そのため、longjmp() が実行された後、
'volatile' 修飾子を変数の定義に追加すると、その変数がスコープ内にある限り、その変数を使用するためだけにストレージが予約されます。setjmp と longjmp の間で何が起こっても、コントロールが変数が宣言されたスコープを離れていなければ、その場所を他の目的に使用することはできません。