パソコン上で動かすプログラムを書く人だとあまり使わないかもしれませんね.
ただ, #1の方もおっしゃる様に, ハードウェアに近い分野では必要になる場合もあります.
volatile修飾子がついた変数には最適化が働かなくなります.
たとえば, 次のようなコードがあるとします.
long counter;
printf("a\r\n");
for( counter = 0; counter < 100000; counter++ );
printf("b\r\n");
for( counter = 0; counter < 100000; counter++ );
printf("c\r\n");
上記コードでは, for文で無意味なループを回して無駄時間を作っているつもりです.
a, b, cの間に少しタイムラグができるはずです.
(実際にはとわからないと思いますが)
ただ, 前のコードは実行速度の点でコンパイラから見ても明らかに無駄です.
したがって, コンパイラは次の様な具合にコードを最適化してしまう場合があります. (処理系依存です)
long counter;
printf("a\r\n");
printf("b\r\n");
printf("c\r\n");
counter = 100000;
処理が終わった時点では最初のコードと最適化後のコードは同じ事ですが,
無駄処理で時間稼ぎをしていた部分が無くなってしまいました.
処理速度向上といえばそうですが, これでは困ります.
(なお, counter変数を後で使わない場合は変数の存在自体が無かった事にされたりもします)
そんな時に, counter変数の宣言時にvolatileをつけて
volatile int counter;
といった具合にすると, counter変数に関連する処理は最適化の対象外となるため,
プログラマが書いたとおりに動作するようになります.
なお, 先のコードは説明の為のコードであまり意味がありませんが,
実際だと「メモリマップドI/O」(メモリの特定のところにデータを書き込むと
ハードウェア的に何らかの動作が起こる仕組み)
などをいじる時はvolatile修飾子が必須となります.
お礼
likipon様へ ご回答ありがとうございました。 わかりやすい説明とサンプルを示していただきありがとうございました。やっとvolatileの意味が理解できました。 ウチの開発環境で、volatileの有無で動作にどのような違いがあるのかを試してみたところはっきりと違いがあらわれたので確認することが できました。ありがとうございました。