1. ホーム
  2. c

[解決済み] volatile int * p "のような揮発性ポインタはなぜ有用なのですか?

2023-06-05 23:28:44

質問

volatile は、参照を最適化しないようにコンパイラに指示することで、すべての読み取り/書き込みがレジスタに格納された値を使用せず、実際のメモリアクセスを行うようにします。私はこれが普通の変数に有用であることは理解できますが、どのように volatile がポインタにどのように影響するのか理解できません。

volatile int *p = some_addr;
int a = *p; // CPU always has to load the address, then does a memory access anyway, right?

と宣言されている場合、何が違うのでしょうか? int *p = some_addr ?

どのように解決するのですか?

フォームのポインタ

volatile int* p;

へのポインタです。 int へのポインタで、コンパイラはこれを volatile . つまり、コンパイラは、変数 p が指す変数が変更された可能性があるとコンパイラが判断することを意味します。 例えば、もし私が p を通常の整数を指すように設定した場合、 読み書きのたびに *p を読み書きするたびに、コンパイラはその値が予期せず変更された可能性があることを認識します。

もう一つの使用例として volatile int* : もしあなたが int として volatile を指定した場合、通常の int* . 例えば、こんなのはダメです。

volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!

この理由は,C コンパイラが ptrvolatile の値をキャッシュしている可能性があります。 *ptr の値をレジスタに不正にキャッシュしてしまうかもしれません。実際、C++では、上記のコードはエラーになります。 その代わり、こう書くべきです。

volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!

ここで、コンパイラは ptr を指していることを記憶しています。 volatile int を指しているため、このメソッドは *ptr .

最後にもう一つ細かいことを言うと、あなたが議論したポインタは volatile int . こんなこともできます。

int* volatile ptr;

これは、ポインタ 自体 volatile であるため、コンパイラはポインタをメモリにキャッシュしたり、ポインタ値が他の何か(ハードウェアなど)によって再割り当てされるかもしれないので、最適化しようとしてはいけないことを意味します。 この獣を手に入れたいなら、これらを組み合わせてもよいでしょう。

volatile int* volatile ptr;

これは、ポインタと被指定者の両方が予期せず変更される可能性があるということです。コンパイラはポインタ自体を最適化することはできませんし、指されているものを最適化することもできないのです。

これが役に立つといいのですが。