Oracle Solaris Studio 12.2: C ユーザーガイド

6.6.6 volatile の使用例

volatile は、通常、次の 4 つのオブジェクトに使用します。

最初の 3 つの例はすべて、特定の動作を行うオブジェクトのインスタンスです。つまり、その値は、プログラムの実行中の任意の時点で変更できます。したがって、外見上は無限ループに見える次のコードは、


flag = 1;
while (flag);

flagvolatile 修飾型を持つ間は有効な文となります。おそらく、ある非同期イベントが将来 flag をゼロに設定することもあります。volatile 修飾型を持たない場合、flag の値はループ本体内では変更されないため、コンパイルシステムによって前述のループは、完全に flag の値を無視する本当の無限ループに変更されることもあり得ます。

4 番目の例は、setjmp を呼び出す関数に対して局所的な変数を含んでいるため、より複雑です。setjmplongjmp の動作についての細字部分には、4 番目の例に一致するオブジェクトの値は保証されないという注記があります。もっとも望ましい動作を行うためには、setjmp を呼び出す関数と longjmp を呼び出す関数の間で、longjmp がすべてのスタックフレームを検査して、保存されたレジスタ値と比較することが必要です。スタックフレームは非同期的に作成される可能性があるため、この作業はより難しくなります。

自動オブジェクトを volatile 修飾型で宣言したとき、コンパイルシステムは、プログラマが書いたものと完全に一致するコードを生成します。したがって、このような自動オブジェクトに対する最新の値は常に、レジスタではなく、メモリー内に存在します。そして、longjmp が呼び出されたときに最新であることが保証されます