Volatileキーワードは、コンパイラーが変数に対して微妙な変更の中でも特に特定の最適化を実行するのを防ぐためにCで使用されます。
例えば;
volatile int my_int = 0;
整数を作成します。状況によっては、次の最適化が妨げられる場合があります。
while(my_int == 0); // Loop until my_int != 0
最適化:
while(1); // Loop infinity.
これは、割り込み関数呼び出しによって変数が変更される可能性がある状況など、組み込みシステムで頻繁に発生する状況を含む状況で役立ちます。この手法が役立つ例は他にもたくさんあります。 my_int
は、このような関数によって変更されるフラグである場合があります。 (これは単なるおもちゃのモデルです。)
ただし、関数によって変更されたデータが配列である場合を考えてみてください。データはポインタによってポイントされるかもしれません。
unsigned char* my_data = new unsigned char[256];
この場合、my_dataがこの質問のこの特定の状況でグローバル変数であることを考えると、[1] volatile
キーワードは冗長ですか、それともまだ必要ですか?
[1]それは問題ではないかもしれません。
答えがvolatileキーワードが必要な場合、正しい構文は何ですか?
例えば、 volatile unsigned char* my_data
、I assumeは、ポインター自体が揮発性であり、ポインターが指すデータではないことを宣言します。
最後に、CとC++での使用に違いはありますか?
はい、volatile
が必要であり、正しい宣言は次のとおりです。
volatile unsigned char *my_data;
これは、my_data
が揮発性のunsignedcharへのポインタであることを宣言します。
ポインタ自体を揮発性にするには、代わりにこれが必要になります。
unsigned char *volatile my_data;
そしてもちろん、ポインタとポイントされたデータの両方が揮発性である可能性があります:
volatile unsigned char *volatile my_data;
CとC++の間に違いはありません。
フィリペゴンサルベスはすでに回答を提供していますが、少し詳しく説明したいと思います。
基本的に、プログラムが変数の値を本当に賢くしようとせずに本当に考慮したいときはいつでも、volatileキーワードが必要です。変数の種類は関係ありません。コンパイラーが割り当てと呼び出しの間の変数への変更を認識できない場合、それはおそらく最適化されます(もちろん、設定によって異なります)。
コンパイラのPOVから、イベントのシーケンスは"assign 0 to Var"->"do unrelated stuff, but surely not touching Var"->"check Var value"
です。変数Varがどこでどのように宣言されたかは関係ありません。コードは、volatile
キーワードが使用されない限り最適化されます。