C 標準には、コンパイラがこれらの関数を異なる方法で実装することを要求する規則はありません。gaたとえば、レジスタを操作する場合、コンパイラはtoからの代入を「最適化」する場合としない場合がありますa(つまり、「最適化」とは、REG にロードgaし、同じ REG を使用して残りの計算を行うことを意味します。としてa)。または、そうでない場合もあります。
ロックフリーのデータ構造を実装したい場合:
- C99 はあなたを助けることができる何も提供しません。
- C11 (ごく最近の標準) は、アトミック データ型を提供します。
C99 を使用している場合は、次のいずれかを行う必要があります。
- ロックを使用します (したがって、ロックフリー コードではありません)。
- アーキテクチャ固有のコードを書く準備をしてください。最低限行う必要があるのは、x86、x86_64、および ARM ISA によって提供されるアトミック操作を使用してロックフリーのデータ構造を実装するこのライブラリで行われているように、最小セットのアトミック操作を使用することです。
この回答の以前のバージョンでは、副次的な問題に触れました(これは に関係しており、実際のvolatile質問には関係ありません):
の実装方法に制限を加えることができるケースが 1 つありますがfunc_b、実際にはここで接線を引いてgaいvolatileます。
gaが volatile の場合、読み取りごとにメモリから新たにロードするga 必要があります。gaつまり in はfunc_b、gaメモリから 2 回ロードされます。比較のために 1 回、戻り値を計算するために 1 回。予想される使用法は、たとえばga、メモリにマップされた I/O ポートを参照するとします。次に、2 つの読み取りの間に値がga変更された場合、これが戻り値に反映されます。ただし、別のスレッドで変更する場合はga、正常な/定義された動作を期待しないでください。
一方、修飾子がないからといって、 で が 1 回だけ読み取られるvolatileわけではありません。そして、「揮発性の反対」である修飾子はありません。gafunc_b