volatile は、通常、次の 4 つのオブジェクトに使用します。
メモリーにマップされた入出力ポートであるオブジェクト
複数の並行プロセス間で共有されるオブジェクト
非同期シグナルハンドラによって変更されるオブジェクト
setjmp を呼び出す関数中で宣言され、その値が setjmp への呼び出しとそれに対応する longjmp への呼び出し間で変更される自動記憶オブジェクト
最初の 3 つの例はすべて、特定の動作を行うオブジェクトのインスタンスです。つまり、その値は、プログラムの実行中の任意の時点で変更できます。したがって、外見上は無限ループに見えます。
flag = 1; while (flag) ;
これは、flag が volatile 修飾型を持つ間は有効です。おそらく、ある非同期イベントが将来 flag をゼロに設定することもあります。それ以外の場合、flag の値はループ本体内では変更されないため、コンパイルシステムは上記ループを、完全に flag の値を無視する本当の無限ループに変更できます。
4 番目の例は、setjmp を呼び出す関数に対して局所的な変数を含んでいるため、より複雑です。setjmp と longjmp の動作についての細字部分には、4 番目の例に一致するオブジェクトの値は保証されないという注記があります。もっとも望ましい動作を行うためには、setjmp を呼び出す関数と longjmp を呼び出す関数の間で、longjmp がすべてのスタックフレームを検査して、保存されたレジスタ値と比較することが必要です。スタックフレームは非同期的に作成される可能性があるため、この作業はより難しくなります。
自動オブジェクトを volatile 修飾型で宣言したとき、コンパイルシステムは、プログラマが書いたものと完全に一致するコードを生成します。したがって、このような自動オブジェクトに対する最新の値は常に、レジスタではなく、メモリー内に存在します。そして、longjmp が呼び出されたときに最新であることが保証されます。