
No.3ベストアンサー
- 回答日時:
パソコン上で動かすプログラムを書く人だとあまり使わないかもしれませんね.
ただ, #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の有無で動作にどのような違いがあるのかを試してみたところはっきりと違いがあらわれたので確認することが
できました。ありがとうございました。
No.6
- 回答日時:
参考URLに、最適化される前とされた後のコードが載っています。
非常に単純なコードですので、わかりやすいと思いますよ。
ちなみに、NO3さんの「無駄ループが無くなるのを防ぐ」という目的ですが、volatileをつけても効果がないコンパイラもあると聞いたことがあります。
うろ覚えですが・・・。
基本は、NO3さんの「メモリマップドI/O」とか、NO1さんの並列処理のためではないでしょうか。
PCプログラミングでも、マルチスレッドやソフトウェア割り込みなどで必要になってきますね。
参考URL:http://www.cmagazine.jp/src/kinjite/c/variable.h …
1839cc様へ
ご回答ありがとうございました。
とてもご丁寧に参考URLまで教えていただきまして
感謝しています。ありがとうございました。
>基本は、NO3さんの「メモリマップドI/O」とか、NO1さんの並列処理
なるほど。これからの学習の課題になりそうです。
学習の方向付けが出来ましたことを感謝します。
ありがとうございました。
No.5
- 回答日時:
実は標準ライブラリの中にも、それを使うときはvolatile修飾子を付けることを要求している場合があります。
具体的には、signal関数で登録するシグナル処理ルーチンで操作するsig_atomic_t型の変数であり、setjmpマクロやlongjmp関数を使うときの自動変数です。これらの関数などについて調べてみるとよいでしょう。
# volatile修飾子が気になっているぐらいですから、まったくの初心者ではないと理解しています。
jacta様へ
ご回答ありがとうございました。
ご指摘の関数につきましては、これから一つずつ解決していきたい
と思います。方向付けが出来ましたことを感謝します。
ありがとうございました。
No.4
- 回答日時:
専門的な知識があると非常に役に立ちます。
先に解答された方は知識が豊富でわかりやすい解説がなされています。ならば、私は超簡単に書いてみようかと.....
貴方の友達(コンパイラは友達ですよw)に仕事を依頼しましょう。
仕事内容をメモに書いて渡します。友達はそれに従って仕事をします。
しかし、その内容がそのまま仕事として反映されるわけではなく、『多分問題ないだろう』と友達が判断した場合、何かを省いたり、工程を前後させて速度を優先させる可能性があります。
もし、貴方が友達の勝手な判断を嫌い、最適化を許さないならばvolatileを付けてあげます。
まあ、友達から仕返しは無いと思いますが......使う機会が無いか...
No.2
- 回答日時:
規格上, volatile は「処理系の感知しない原因で値が変化することがある」という意味です. で, 結果として「最適化しない」ということになります.
これがどんな効果を持つかというと, volatile がない場合には処理系が「ああ, この変数の値は変化しないね」と判断するとその値をレジスタ (など) にコピーし, いちいちメモリ (など) から読み込まないことがあります. それに対し, volatile が付いているとその変数を参照するたびに必ず値を調べに行きます.
Tacosan様へ
ご回答ありがとうございました。
とてもわかりやすい説明をありがとうございました。
コンパイラが具体的にどういうときに最適化するのかを確認できる
簡単な実行例があればありがたいのですが、どうかご教授お願いします。

No.1
- 回答日時:
コンパイラに最適化を行う機能があります。
貴方がプログラムを書いた場合、コンパイラはその利用頻度や利用範囲を元に、変数をCPU内レジスタに割り当てるか、RAMに割り当てるかを決めます。
しかし、変数をレジスタに割り当てられては困る場合があります。
たとえば、ハードウェアの制御レジスタは特定のアドレスをアクセスしてR/Wしなければならないので、メモリ上の変数に置き換えられたり、レジスタに割り当てられては役に立ちません。変数の値を変えてもハードウェアの制御レジスタが書き換わらないのでハードウェアは動作せず、バグになってしまいます。
このような変数にvolatile宣言を行うことで、最適化の対象外であることをコンパイラに伝えるのです。
PCですとドライバソフトを書く場合に必須です。
ファームウェアでも常用します。
kazusone様へ
ご回答ありがとうございました。
誤解を恐れずにいうならば、
変数をコンパイルの最適化の対象外にするということは、
コンパイラの判断で変数をレジスタにおくことによって処理を高速化
すると、変数の値が変化してもその変更内容が反映されくなるので、
反映されるようにするためにvolatileを変数に修飾して、
最適化の対象外にするということでよろしいのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DLLファイルの逆コンパイラにつ...
-
unsigned long long 型のフォー...
-
未使用引数の注意文出力を回避...
-
組み込みソフト。ROM領域にデータ
-
ソフトの開発言語を調べる方法
-
C言語の規格
-
パーサーに関する良本
-
N88 BASICのコンパイラ
-
VB6のコンパイラ
-
COBOLの論理演算子について質問...
-
cc と gcc の違い
-
python エラー
-
<unistd.h>をVisualStudioでつ...
-
バッチからsqlplusの接続エラー...
-
未解決の外部シンボル
-
” OS ビルド ” の意味が分か...
-
visual studio2019でデバッグが...
-
Win8 で ASPのデバッグをするに...
-
ASP.NETのDLL入れ替えについて
-
fatal error LNK1112
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DLLファイルの逆コンパイラにつ...
-
unsigned long long 型のフォー...
-
ソフトの開発言語を調べる方法
-
組み込みソフト。ROM領域にデータ
-
C++でデスクトップGUIアプリ開...
-
パーサとコンパイラの違いって?
-
【C言語】 型のサイズについて
-
COBOLのALPHABET...
-
<conio.h>?
-
printfなど、標準関数のソース...
-
COBOLの論理演算子について質問...
-
cc と gcc の違い
-
DLLの呼び出され方が分かりません
-
AIXとCOBOLについて
-
PICマイコンのプログラムカウン...
-
リリースモードとデバッグモー...
-
C++Builder → Visual C++ 移植...
-
C++DLLの明示的リンクに関して
-
cobolで実行環境って何ですか?
-
C言語の規格
おすすめ情報