回答編集履歴

2 さらに誤字修正

koach

koach score 14

2016/07/04 12:01  投稿

volatile 理解するの苦しみますよね。
結論から言うと volatileは コンパイラ最適化オプションを有効にした上で
最適化対象としたくない変数操作がある変数に対して適用します。
以下、補足説明です。
コンパイラには 最適化オプションというのがあって、
最適化が有効になっていると、定義した変数を利用しないと、不要なコードとして取り扱われ
アセンブラレベルのコードが生成されなくなるケースがあるのです。
例えば
```ここに言語を入力
int *a = (int *)0x100000; // 読み対象レジスタのアドレスを0x100000と過程
int *a = (int *)0x100000; // 読み対象レジスタのアドレスを0x100000と仮定
void func()
{
   int *b;
   b = a;  // #1
   /* 変数bを利用するコードを書かない */
}
```
上記のサンプルは、変数bが参照されないので、最適化オプションが有効時は、
#1に相当するアセンブラコードが生成されません。
(アセンブラコードを生成するにはお使いのコンパイラのオプションを調べてください)
※ 最適化オプションが無効な場合は、#1に相当するアセンブラコードも生成されます。
ところが、
変数に値を代入する操作(具体的にリード)だけでも意味をもつ場合あります。
特に組込プログラミングにおいては レジスタ値を読むということだけでも意味がある場合があります。
その場合は次の様に記述することになります。
```ここに言語を入力
int *a = (int *)0x100000;  // 読み対象レジスタのアドレスを0x100000と過程
int *a = (int *)0x100000;  // 読み対象レジスタのアドレスを0x100000と仮定
void func()
{
   volatile int *b;
   b = a;  // #1
   /* 変数bを利用する事がない */
}
```
上記の場合、最適化オプションが有効な場合でも#1に相当するアセンブラコードは生成されます。
常に最適化オプション無効としてコンパイルするならこんな考慮は必要ないのですが
組込プログラミングにおいては、対象となるハードウエアはPC程の多くのメモリを積んでいないので
可能な限りメモリ使用量を減らしたいケースが殆どなので、
最適化オプション有効+必要に応じてvolatile宣言
というケースが多いです。
ちょっと長くなりましたが、ポイントつかんで頂けたでしょうか。
1 誤字修正。コメント文の適正化

koach

koach score 14

2016/07/04 12:00  投稿

volatile 理解するの苦しみますよね。
結論から言うと volatileは コンパイラ最適化オプションを有効にした上で
最適化対象としたくない変数操作がある変数に対して適用します。
以下、補足説明です。
コンパイラには 最適化オプションというのがあって、
最適化が有効になっていると、定義した変数を利用しないと、不要なコードとして取り扱われ
アセンブラレベルのコードが生成されなくなるケースがあるのです。
例えば
```ここに言語を入力
int *a = (int *)0x100000; // 0x10000に特に意味はない
int *a = (int *)0x100000; // 読み対象レジスタのアドレスを0x100000と過程
int func()
void func()
{
   int *b;
   b = a;  // #1
   /* 変数bを利用するコードを書かない */
}
```
上記のサンプルは、変数bが参照されないので、最適化オプションが有効時は、
#1に相当するアセンブラコードが生成されません。
(アセンブラコードを生成するにはお使いのコンパイラのオプションを調べてください)
※ 最適化オプションが無効な場合は、#1に相当するアセンブラコードも生成されます。
ところが、
変数に値を代入する操作(具体的にリード)だけでも意味をもつ場合あります。
特に組込プログラミングにおいては レジスタ値を読むということだけでも意味がある場合があります。
その場合は次の様に記述することになります。
```ここに言語を入力
int *a = (int *)0x100000; // 0x10000に特に意味はない
int *a = (int *)0x100000;  // 読み対象レジスタのアドレスを0x100000と過程
int func()
void func()
{
   volatile int *b;
   b = a;  // #1
   /* 変数bを利用する事がない */
}
```
上記の場合、最適化オプションが有効な場合でも#1に相当するアセンブラコードは生成されます。
常に最適化オプション無効としてコンパイルするならこんな考慮は必要ないのですが
組込プログラミングにおいては、対象となるハードウエアはPC程の多くのメモリを積んでいないので
可能な限りメモリ使用量を減らしたいケースが殆どなので、
最適化オプション有効+必要に応じてvoltile宣言
最適化オプション有効+必要に応じてvolatile宣言
というケースが多いです。
ちょっと長くなりましたが、ポイントつかんで頂けたでしょうか。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る