序文
日々の勉強の過程で型修飾子volatileを見かけ使い方がわからなかったので調べて勉強しました。
理論
volatile キーワードは型修飾子です。変数が volatile を使用して宣言されると、前の命令がそこからデータを読み取ったばかりであっても、システムは常にその変数が配置されているメモリからデータを再読み取りします (コンパイラはもはや制御しません)この変数のアクセス コードは最適化されます)。
例
コードを実行する
#include <stdio.h>
void main()
{
int i=10;
int a = i;
printf("i= %d/n",a);
//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
__asm {
mov dword ptr [ebp-8], 20h
}
int b = i;
printf("i= %d/n",b);
}
プログラムをデバッグ バージョン モードで実行すると、出力は次のようになります。
i = 10
i = 32
次に、プログラムをリリース バージョン モードで実行すると、出力結果は次のようになります。
i = 10
i = 10
この結果の理由は、最適化がリリース モードで実行されるためです。コンパイラは、i からデータを読み取る 2 つのコード間のコードが i に対して操作されていないことを検出し、最後に読み取られたデータを自動的に b に配置します。
変数 i の宣言に修飾子 volatile を追加すると、データを読み込むたびにそのアドレスから読み込まれるようになり、上記の問題は発生しなくなります。
volatile int i=10;
付け加えておきますが、私が参照している上記のコードはオンラインで書かれており、アセンブリ内の元のオフセット値は 4 です。デバッグを通じてスタックの先頭を調べました。
該当シーン
- 並列デバイスのハードウェアレジスタ(ステータスレジスタなど)
- 割り込みサービスルーチンでアクセスされる非自動変数 (非自動変数)
- マルチスレッドアプリケーションの複数のタスクで共有される変数
結論
それでいいよ!