15

(始める前に:このトピックに関する既存の 質問があることは知っていますが、これが問題である理由の答えは見つかりませんでした。定期的に行っており、潜在的な問題が発生しているかどうかを知りたいです。)

関数呼び出しで volatile 修飾子を破棄すると、コンパイラの警告が表示される理由が知りたいです。

状況は次のとおりです。

volatile uint8_t thingy;
void awesome_function(uint8_t *arg);

awesome_function(&thingy); << warning

さて、私の理解では、volatile修飾子は変数をコンパイラの制御外で変更される可能性があるものとしてマークします。したがって、特定の最適化 (最も重要なのは、私の経験では、「未使用」変数の削除) が無効になっています。

ただし、変数を としてマークすると、このスコープvolatileでの最適化を防止することが懸念されます。変数を関数に渡すと、通常、その関数内で標準の最適化が適用されます。*

これは、コンパイラが関数から変数を削除したい場合でも当てはまります (私が通常避けようとしている最適化)。そうしても、このスコープでの使用には影響しません。関数 (の結果) 自体が、私が興味を持っているシーケンス ポイント (および左辺値) です。

では、現在のスコープで並べ替えが有効にならないのに、関数呼び出しに関して修飾子を破棄すると警告になるのはなぜですか? volatileこれは、変数に対して許可されていない、呼び出された関数のスコープでの潜在的な並べ替えのためですか? もしそうなら、なぜこれが現在のスコープに関して問題なのですか?

(* これは通常、このような呼び出しが非同期操作を開始するために使用され、最終的には関数に渡されたポインターで動作するためです。その関数は、最終的に要求どおりに更新することを条件として、ポインターで好きなことを行うことができます。volatile修飾子はそこにあります。ローカル変数が非同期に変更されることをコンパイラに警告します。)

4

3 に答える 3

30

ここでの警告は、volatileポインター オブジェクトへのポインターがある場合、ポインターの値が外部ソースから変更される可能性があるとユーザーが正直に信じているとコンパイラが想定しているためです。非オブジェクトへのポインターを要求する関数にこのポインターを渡すvolatileと、コンパイラーは、オブジェクトが変更される可能性があるという事実を正しく考慮しない方法で関数呼び出しが最適化される可能性があることを警告します。

volatileこれを行っても問題ないことを確実に知っているということは、次のようにを削除する明示的なキャストを入れたいということを意味します。

awesome_function((uint8_t*) &thingy);

これは、コンパイラに「ここで削除していることを知っているvolatileので、それについて警告しないでください」と明示的に伝えます。結局のところ、警告の要点は、これに気付いていない可能性があるということです。

良い類似物は、 について考えることconstです。オブジェクトへのポインターがある場合、ポインターをconst介してそのオブジェクトを変更しないことを約束しています。非オブジェクトへのポインターを受け取る関数にこのポインターを渡そうとすると、関数をconst介して誤って値を変更してしまう可能性があることにコンパイラーが気付くため、警告が表示されます。明示的なキャストを入れることは、コンパイラーに「はい、このポインターを使用して何かを変更するべきではないことはわかっていますが、自分が何をしているのかを知っていることを約束します」と伝える方法です。

お役に立てれば!

于 2013-04-15T01:05:03.060 に答える
3

理由は、volatile最適化を妨げることではありません。これは volatile 変数に対して行われる可能性のあるものの 1 つですが、その理由は、変数が C の「仮想マシン」の制御外で変更される可能性があることをコンパイラに示すためであり、それについてあまり多くの仮定を行うべきではありません。 .

そのためには、変数のスコープではなく、変数自体のプロパティです。

変数が揮発性である場合、その変数へのポインターを渡しても、魔法のように非揮発性になるわけではなく、揮発性変数のアドレスが得られるだけです。それはそうあるべきです。

変数のスコープに基づいて最適化を選択したいだけの場合、それvolatileは仕事のためのツールではありません. キャスト中にその特定の警告を無効にするなど、他の(おそらく非標準の)方法を見つける必要があります#pragma warning-これはもちろん環境によって異なります。

于 2013-04-15T01:05:11.137 に答える