[編集] 背景を読むために、そして明確にするために、これは私が話していることです: volatile キーワードの紹介
組み込みシステム コードを確認する際によく見られるエラーの 1 つは、スレッド/割り込み共有データの volatile が省略されていることです。volatile
しかし、私の質問は、アクセス関数またはメンバー関数を介して変数にアクセスするときに使用しないことが「安全」かどうかです。
簡単な例; 次のコードで...
volatile bool flag = false ;
void ThreadA()
{
...
while (!flag)
{
// Wait
}
...
}
interrupt void InterruptB()
{
flag = true ;
}
... flag
ThreadA の読み取りが最適化されないように、変数は揮発性でなければなりませんが、関数を介してフラグが読み取られた場合は...
volatile bool flag = false ;
bool ReadFlag() { return flag }
void ThreadA()
{
...
while ( !ReadFlag() )
{
// Wait
}
...
}
...flag
まだ揮発性である必要がありますか? 揮発性であっても害がないことは理解していますが、私の懸念は、それが省略され、省略が発見されない場合です。これは安全でしょうか?
上記の例は自明です。実際のケース (および質問の理由) では、タスク オブジェクトの派生元である抽象クラス cTask が存在するように、RTOS をラップするクラス ライブラリがあります。このような「アクティブな」オブジェクトには通常、オブジェクトのタスク コンテキストで変更されるデータにアクセスするメンバー関数がありますが、他のコンテキストからはアクセスされます。そのようなデータが揮発性であると宣言されることは重要ですか?
私は、実際のコンパイラが何をするかよりも、そのようなデータについて何が保証されているかに本当に興味があります。私は多くのコンパイラをテストし、それらがアクセサを介した読み取りを最適化しないことを発見するかもしれませんが、ある日、この仮定が正しくないコンパイラまたはコンパイラ設定を見つけます. たとえば、関数がインライン化されている場合、そのような最適化は直接読み取りと変わらないため、コンパイラにとっては簡単であると想像できます。