(始める前に:このトピックに関する既存の 質問があることは知っていますが、これが問題である理由の答えは見つかりませんでした。定期的に行っており、潜在的な問題が発生しているかどうかを知りたいです。)
関数呼び出しで volatile 修飾子を破棄すると、コンパイラの警告が表示される理由が知りたいです。
状況は次のとおりです。
volatile uint8_t thingy;
void awesome_function(uint8_t *arg);
awesome_function(&thingy); << warning
さて、私の理解では、volatile
修飾子は変数をコンパイラの制御外で変更される可能性があるものとしてマークします。したがって、特定の最適化 (最も重要なのは、私の経験では、「未使用」変数の削除) が無効になっています。
ただし、変数を としてマークすると、このスコープvolatile
での最適化を防止することが懸念されます。変数を関数に渡すと、通常、その関数内で標準の最適化が適用されます。*
これは、コンパイラが関数から変数を削除したい場合でも当てはまります (私が通常避けようとしている最適化)。そうしても、このスコープでの使用には影響しません。関数 (の結果) 自体が、私が興味を持っているシーケンス ポイント (および左辺値) です。
では、現在のスコープで並べ替えが有効にならないのに、関数呼び出しに関して修飾子を破棄すると警告になるのはなぜですか? volatile
これは、変数に対して許可されていない、呼び出された関数のスコープでの潜在的な並べ替えのためですか? もしそうなら、なぜこれが現在のスコープに関して問題なのですか?
(* これは通常、このような呼び出しが非同期操作を開始するために使用され、最終的には関数に渡されたポインターで動作するためです。その関数は、最終的に要求どおりに更新することを条件として、ポインターで好きなことを行うことができます。volatile
修飾子はそこにあります。ローカル変数が非同期に変更されることをコンパイラに警告します。)