C言語volatile

3099 ワード

volatileはコンパイラのコンパイルの結果に影響し、volatile変数はいつでも変化する可能性があることを指摘し、volatile変数に関する演算はコンパイル最適化を行わず、エラーを回避する(VC++はrelease版実行可能コードを生成する際に
コンパイル最適化を行い、volatileキーワードの変数に関する演算を加えると、コンパイル最適化は行われません.)
例:
 
  
volatile int i=10;
int j = i;
...
int k = i;

volatileは、コンパイラiがいつでも変化する可能性があることを示し、それを使用するたびにiのアドレスから読み出さなければならないため、コンパイラが生成した実行可能コードは、iのアドレスからデータを読み直してkに置く.最適化された方法は、コンパイラによって
iからデータを読み出すコード間のコードが2回もiを操作していないことがわかり、前回読んだデータをkに自動的に格納します.iから読み直すのではなく.これにより、iがレジスタ変数であるか、ポートデータを表すと
エラーが発生しやすいので、volatileは特殊なアドレスへの安定したアクセスを保証し、エラーは発生しません.
/**********************
volatileとして定義された変数は、コンパイラがこの変数の値を仮定しないように、この変数が予想外に変更される可能性があるということです.正確には、オプティマイザはこの変数を使用するたびに注意深く再読み込みする必要があります.
この変数の値は、レジスタに保存されたバックアップではありません.volatile変数のいくつかの例を次に示します.
1)パラレルデバイスのハードウェアレジスタ(例:ステータスレジスタ)
2)割り込みサービスサブルーチンでアクセスされる非自動変数(Non-automatic variables)
3)マルチスレッドアプリケーションでいくつかのタスクで共有される変数でこの質問に答えられない人は雇われない.
これはCプログラマーと組み込みシステムプログラマーを区別する最も基本的な問題だと思います.組み込み型の奴らはハードウェア、割り込み、RTOSなどとよく付き合い、volatile変数を使う必要がある.volatileの内容がわからない
災難をもたらすだろう.面接された人がこれが質問だと正しく答えたとしたら(うん、そうなのか疑問)、こいつがvolatileの完全な重要性を直接知っているかどうか、少し深く考えてみよう.
1)1つのパラメータはconstでもvolatileでもよいですか?なぜか説明する.
2); ポインタはvolatileですか?なぜか説明する.
3); 次の関数にエラーがあります.
 
  
int square(volatile int *ptr)

 {
    return *ptr * *ptr;
}


次は答えです.
1)はい.1つの例は、読み取り専用のステータスレジスタである.それはvolatileです.予想外に変わる可能性があるからです.これはconstです.プログラムはそれを修正しようとしないからです.
2); はい.これはあまりよくありませんが.1つの例は、サービスサブルーチンがbufferを指すポインタを修正する場合である.
3)このコードは少し変態です.このコードの目的は、ポインタ*ptrが値の二乗を指すことですが、*ptrがvolatile型パラメータを指すため、コンパイラは次のようなコードを生成します.
 
  
int square(volatile int *ptr)

{
    int a,b;
     a = *ptr;
     b = *ptr;
    return a * b;
}


*ptrの値は予想外に変化する可能性があるため、aとbは異なる可能性がある.その結果、このコードはあなたが望んでいる平方値ではない可能性があります.正しいコードは次のとおりです.
 
  
long square(volatile int *ptr)
{
     int a;
     a = *ptr;
     return a * a;
 }

ビット操作(Bit manipulation)
//*********************
埋め込みプログラミングではvolatileというキーワードがよく使われていますが、ネットで調べたところ、彼の使い方は以下の2つにまとめることができます.
一:compilerに最適化できないことを伝える
たとえば、あるアドレスに2つのコマンドを送信します.
 
  
int *ip =...; //    

*ip = 1; //    

*ip = 2; //


以上のプログラムcompilerは最適化される可能性があります.
int *ip = ...;  
*ip = 2;  
その結果、最初のコマンドが失われました.
volatileを使用すると、compilerはプログラムの本来の意味を保証するために最適化を許可しません.
volatile int *ip = ...;  
*ip = 1;    *ip = 2;  
compilerを最適化しても、2回の値付け文を1つにすることはありません.他の最適化しかできません.これはdevice driverプログラマーに役立ちます.
二:volatileで定義された変数はプログラムの外で変更され、毎回メモリから読み込まなければならず、cacheやレジスタに置いて繰り返し使用できないことを示します.
のように
 
  
volatile char a;          

a=0;       

while(!a)

{ //do some things;  }       

doother();


volatile doother()がなければ実行されません