最終更新:2026-10-12
C++ volatile キーワード¶
著者について:¶
個人公式アカウント(WeChat):

1.volatile¶
volatile 修飾された変数は、その読み書きを行う際に、観測可能な副作用**を引き起こします。そして、この観測可能な副作用は、**プログラム外の要因によって決定されます。
2.volatileの応用¶
(1)並行デバイスのハードウェアレジスタ(例:ステータスレジスタ)。 あるデバイスを初期化するとします。このデバイスのあるレジスタが0xff800000だとします。
int *output = (unsigned int *)0xff800000; //定义一个IO端口;
int init(void)
{
int i;
for(i=0;i< 10;i++)
{
*output = i;
}
}
(2)割り込みサービスルーチンの中でアクセスされる変数;
static int i=0;
int main()
{
while(1)
{
if(i) dosomething();
}
}
/* Interrupt service routine */
void IRS()
{
i=1;
}
(3)マルチスレッドアプリケーションで複数のタスクから共有される変数。 複数のスレッドがある変数を共有するとき、その変数の値はあるスレッドによって変更されるため、volatileで宣言すべきです。その役割は、コンパイラの最適化によって変数がメモリからCPUレジスタへロードされるのを防ぐことです。あるスレッドが変数を変更した後、他のスレッドに速やかに同期されずプログラムのエラーを引き起こします。volatileの意味は、コンパイラにこの変数を操作するたびに必ずメモリから本当に値を読み出すようにさせ、すでにレジスタにある値を使わせないことです。例は次の通りです:
volatile bool bStop=false; //bStop 为共享全局变量
//第一个线程
void threadFunc1()
{
...
while(!bStop){...}
}
//第二个线程终止上面的线程循环
void threadFunc2()
{
...
bStop = true;
}
volatileの応用シナリオを理解しているかどうかは、C/C++プログラマと組込み開発プログラマを見分ける有効な方法です。組込みをやる者たちはよくハードウェア、割り込み、RTOSなどと付き合い、これらにはすべてvolatile変数が必要です。volatileを理解していなければ、プログラム設計に災難をもたらすでしょう。
3.volatileのよくある質問¶
次の質問で、面接者がvolatileを本当に理解しているかどうかを確かめられます。 (1)ある引数はconstかつvolatileにできますか?なぜですか? できます。例は読み取り専用のステータスレジスタです。予期しない形で変更される可能性があるためvolatileです。プログラムがそれを変更しようとすべきではないためconstです。
(2)ポインタはvolatileにできますか?なぜですか? できます。これはあまり一般的ではありませんが。例は、割り込みサービスルーチンがあるbufferを指すポインタを変更する場合です。
(3)次の関数には何の誤りがありますか?
このコードは少しひねくれています。その目的はポインタptrが指す値の2乗を返すことですが、ptrはvolatile型の引数を指しているため、コンパイラは次のようなコードを生成します: *ptrの値は予期しない形で変更される可能性があるため、aとbは異なる値になるかもしれません。その結果、このコードが返すのは期待した2乗値ではない可能性があります!正しいコードは次の通りです:4.volatileの使用¶
-
volatile キーワードは型修飾子であり、これで宣言された型の変数は、コンパイラにとって未知の要因(オペレーティングシステム、ハードウェア、他のスレッドなど)によって変更され得ることを示します。したがって、volatileを使って、コンパイラにそのようなオブジェクトを最適化すべきでないと伝えます。
-
volatile キーワードで宣言された変数は、アクセスのたびにメモリから値を取り出さなければなりません(volatileで修飾されていない変数は、コンパイラの最適化によってCPUレジスタから値を取る可能性があります)
- const は volatile であり得ます(例:読み取り専用のステータスレジスタ)
- ポインタは volatile であり得ます
コード学習:
関連トピック¶
- C++ 純粋仮想関数と抽象クラス | C++那些事
- C++ assert アサーション | C++那些事
- C++ ビットフィールド | C++那些事
- C 言語による C++ 多態の実現 | C++那些事
- C++ const 定数と修飾 | C++那些事
- C++ const ファミリー | C++那些事
- C++ 間接参照演算子 * | C++那些事
- C++ 初期化と代入 | C++那些事
- C++ 複数戻り値の書き方 | C++那些事
- C++ mutable キーワード | C++那些事